Simple RecurrenceMax。得分0
我们的英雄 - 亚历克斯已经研究了一个星期。他有 最近得到了一个复发关系来解决其中的一部分 研究。但他没有时间。你能做到吗?
递归关系如下:f(n)= 3 * f(n-1)+ 2 * f(n-2)+ 2 * g(n-1)+3 * g(n-2),g(n)= g(n-1)+ 2 * g(n-2)。
给出初始值f(1),f(0),g(1),g(0)。
你必须输出f(N)mod 10 ^ 9。
输入:
在第一行中,您将获得4个数字:f(1),f(0),g(1),g(0) 分别。在下一行中,您将获得一个整数N。
输出:
输出f(N)mod 10 ^ 9。
约束:
1&lt; = f(0),f(1),g(0),g(1)&lt; = 10 1 <= N <= 10 ^ 18
样本输入(明文链接)
1 1 1 1 4 样本输出(明文链接) 162
这确实是一个非常简单的问题。我只是用6个变量f0,f1,f2,g0,g1,g2进行迭代来解决它。在循环中,我首先计算g2,f2,然后f0 = f1,f1 = f2,g0 = g1,g1 = g2。数据类型在c ++中是长对齐的无符号。
然而,时间限制是1秒,我得到1.06秒。因此,我在测试中仅通过了一个测试用例,其他时间超过了#34;。有没有更快的方法来解决它?
我的代码是:
#include<iostream>
using namespace sdt;
int main()
{
unsigned long long f0, f1, g0, g1, f2, g2;
unsigned long long N;
cin>>f1>>f0>>g1>>g0;
cin>>N;
for(unsigned long long i=2; i<N+1; i++)
{
f2=3*f1+2*f0+2*g1*3*g0;
g2=g1+2*g0;
f0=f1;
f1=f2;
g0=g1;
g1=g2;
}
unsigned long long result=f2%1000000000;
cout<<result;
return 0;
}
答案 0 :(得分:2)
鉴于重复可以写为
具有f(1)
,f(o)
,g(1)
和g(0)
给出的基本条件。现在,要计算f(n)
,我们必须将系数矩阵提高到幂n - 1
。幸运的是,这可以使用log(n)
矩阵乘法来完成。这是exponentiation的一个着名问题。
由于矩阵大小很小,因此复杂度为O(log(n))
。
答案 1 :(得分:1)
1 - 代码与递归关系不同。代码应该是:
f2=3*f1+2*f0+2*g1+3*g0;
2 - 优化代码的一种可能方法是通过这样做来减少繁重计算的数量,这是本例中的乘法:
f2=3*(f1+g0)+2*(f0+g1);
但是,我认为编译器的优化器会自动为您执行此操作,但您可以尝试自己确定。