题意:输入N,输出fib(2^N)%1125899839733759。(P=1125899839733759是素数)
思路:欧拉降幂,因为可以表示为矩阵乘法,2^N在幂的位置,矩阵乘法也可以降幂,所以有ans=a*base^num; num=2^N%(P-1)。
#include<bits/stdc++.h> #define ll long long using namespace std; const ll Mod=1125899839733759; inline ll mul(ll x,ll y,ll p){ return ((x*y-(ll)(((long double)x*y+0.5)/p)*p)%p+p)%p; } struct mat { ll M[3][3]; mat() { memset(M,0,sizeof(M)); } mat friend operator *(mat a,mat b) { mat res; for(int k=1;k<=2;k++) for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) res.M[i][j]=(res.M[i][j]+mul(a.M[i][k],b.M[k][j],Mod))%Mod; return res; } mat friend operator ^(mat a,ll x) { mat res; res.M[1][1]=res.M[2][2]=1LL; while(x){ if(x&1LL) res=res*a; a=a*a; x/=2; } return res; } }; ll qpow(ll a,ll x,ll p){ ll res=1; while(x){ if(x&1LL) res=mul(res,a,p); a=mul(a,a,p); x/=2; } return res; } int main() { int T; ll N,num; scanf("%d",&T); while(T--){ scanf("%lld",&N); num=qpow(2LL,N,Mod-1); num--; if(num<0) num+=Mod-1; mat base,a; base.M[1][1]=base.M[1][2]=base.M[2][1]=1LL; a.M[1][1]=1LL; base=base^num; a=base*a; printf("%lld ",a.M[1][1]); } return 0; }