P1349 广义斐波那契数列

来源:互联网 发布:sql备份 编辑:程序博客网 时间:2024/06/08 02:48

luogu 传送门
我们可以设一个矩阵A={p , 1
                                         q , 0}

ans矩阵{a2 , a1},用ans矩阵*A矩阵的n-2次方,ans[1][1]就是答案了。
正确性自己在纸上画一画就显而易见了。

#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<cstring> #define LL long longusing namespace std;LL p,q,a1,a2,n,MOD;LL A[3][3];LL B[3][3];LL ans[2][2];LL bak[3][3];void Fast_Pow(){    while(n)    {        if(n%2)        {            for(int i=1;i<=2;i++)             for(int j=1;j<=2;j++)              bak[i][j]=B[i][j],B[i][j]=0;            for(int i=1;i<=2;i++)             for(int j=1;j<=2;j++)              for(int k=1;k<=2;k++)               B[i][j]=(B[i][j]+bak[i][k]*A[k][j]%MOD)%MOD;        }        for(int i=1;i<=2;i++)         for(int j=1;j<=2;j++)          bak[i][j]=A[i][j],A[i][j]=0;        for(int i=1;i<=2;i++)         for(int j=1;j<=2;j++)          for(int k=1;k<=2;k++)           A[i][j]=(A[i][j]+bak[i][k]*bak[k][j]%MOD)%MOD;        n/=2;    }}int main(){    scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&MOD);    A[1][1]=p,A[2][1]=q,A[1][2]=1;    B[1][1]=p,B[2][1]=q,B[1][2]=1;    n--;ans[1][1]=a2,ans[1][2]=a1;    if(n==1) {printf("%lld",a1%MOD);return 0;}     if(n==2) {printf("%lld",a2%MOD);return 0;}    n-=2;    Fast_Pow();    ans[1][1]=(ans[1][1]*B[1][1]%MOD+ans[1][2]*B[2][1]%MOD)%MOD;    printf("%lld",ans[1][1]);    return 0;}
原创粉丝点击