题意:F(n)为斐波那契数列的第n项,问你F(F(n)) mod 20160519的值。
发现有循环节,F(26880696)=0,F(26880697)=1,...。
于是两次矩乘快速幂即可。
#include<cstdio> #include<vector> using namespace std; typedef long long ll; typedef vector<ll> vec; typedef vector<vec> mat; mat mul (const mat &A,const mat &B,const ll &MOD){ mat C(A.size(),vec(B[0].size())); for(int i=0;i<A.size();++i){ for(int k=0;k<B.size();++k){ for(int j=0;j<B[0].size();++j){ C[i][j]=(C[i][j]+A[i][k]*B[k][j])%MOD; } } } return C; } mat I; mat Quick_Pow(mat a,ll p,ll MOD){ if(!p){ return I; } mat res=Quick_Pow(a,p>>1,MOD); res=mul(res,res,MOD); if(p&1ll){ res=mul(res,a,MOD); } return res; } int T,n; int main(){ // freopen("f.in","r",stdin); scanf("%d",&T); for(;T;--T){ scanf("%d",&n); I.assign(2,vec(2)); I[0][0]=I[1][1]=1; mat A(2,vec(2)); A[0][0]=A[0][1]=A[1][0]=1; mat F(2,vec(1)); F[0][0]=1; ll t=mul(Quick_Pow(A,n-1ll,26880696ll),F,26880696ll)[0][0]; if(t==0ll){ puts("0"); } else if(t==1ll){ puts("1"); } else{ printf("%lld ",mul(Quick_Pow(A,t-1ll,20160519ll),F,20160519ll)[0][0]); } } return 0; }