题解 P1962 【斐波那契数列】

ouuan

2018-07-11 23:07:30

Solution

看楼上dalao们都是用f[n],f[n+1]推f[n+1],f[n+2]然而我是用f[n],f[n+1]推f[n+2],f[n+3] (然而只是预处理了矩阵的二次方) f[n+2]=f[n]+f[n+1]不用多说 f[n+3]=f[n+1]+f[n+2]=f[n]+2*f[n+1] 因此用来计算的矩阵就是 | 1 | 1 | | :----------: | :----------: | | 1 | 2 | 这样算的话貌似能快一个可以忽略不计的常数.. 嗯,我这篇题解就是从[P1939](https://www.luogu.org/blog/yyfouuan/solution-p1939)那抄过来的..因为我两题都是这样没有重复推的。 代码如下: ``` #include <iostream> using namespace std; const long long M=1000000007; struct matrix { long long a[2][2]={{0,0},{0,0}}; matrix operator*(const matrix& b) const { matrix out; long long i,j,k; for (i=0;i<2;++i) { for (j=0;j<2;++j) { for (k=0;k<2;++k) { out.a[i][j]=(out.a[i][j]+this->a[i][k]*b.a[k][j])%M; } } } return out; } }; int main() { long long n,i; matrix f,ans; f.a[0][0]=f.a[0][1]=f.a[1][0]=1; //初始化为上文所述的矩阵 f.a[1][1]=2; ans.a[0][0]=ans.a[1][1]=1; //初始化为对角线为1的矩阵,即单位矩阵 cin>>n; for (i=62;i>=0;--i) //二进制版快速幂,个人比较喜欢,平常用递归的小伙伴们也可以学一学 { ans=ans*ans; if ((1ll<<i)&((n-1)>>1)) //注意计算的是矩阵的(n-1)/2次方 { ans=ans*f; } } if (n&1) ////输出的时候判断一下n处于向量中的哪个位置,即n%2是几 } { cout<<(ans.a[0][0]+ans.a[0][1])%M; } else { cout<<(ans.a[1][0]+ans.a[1][1])%M; } return 0; } ```