斐波那契数列(矩阵乘法)

洛咕

POJ

题意:求出 f(n) mod 1e9+7 的值.\((n<=10^{18})\)

分析:直接线性递推肯定超时.考虑矩阵快速幂加速递推(这是一个在线性递推中很常用的优化方法).考虑我们已知矩阵\(S(i-1)=[S_{n-1},S_{n}]\),想要得到矩阵\(S(i)=[S_n,S_{n+1}]\),根据矩阵乘法的运算法则可手玩出转移矩阵\(T= [\begin{matrix} 0 & 1 \\1 & 1 \end{matrix}]\).

于是我们可以设初值为\(S(0)=[0,1]\),目标为\(S(n)=S(0)*T^n\),可以借助矩阵快速幂来计算.

时间复杂度\(O(8logn)\)

#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline LL read(){
    LL s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
const LL mod=1e9+7;
struct matrix{
    LL a[2][2];
    matrix operator *(matrix b){//重载'*'
        matrix c;
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                c.a[i][j]=0;
//一定先要初始化
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                for(int k=0;k<2;k++)
                    c.a[i][j]=(c.a[i][j]+1LL*a[i][k]*b.a[k][j])%mod;
        return c;
    }
}S,T;
int main(){
    S.a[0][0]=0;S.a[0][1]=1;//初始矩阵S
    T.a[0][0]=0;T.a[0][1]=1;T.a[1][0]=1;T.a[1][1]=1;//转移矩阵T
    LL n=read();//十年oi一场空...
    while(n){if(n&1)S=S*T;T=T*T;n>>=1;}
//快速幂,我已经重载'*'为矩阵乘法了
    printf("%lld\n",S.a[0][0]%mod);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/PPXppx/p/10587451.html
今日推荐