如果直接用矩阵快速幂,复杂度是
O(n)
的。
因为1125899839733759是质数,所以可以用欧拉定理,求出
2n−1 mod 1125899839733758
就好了。
时间复杂度
O(T⋅23⋅logn)
。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M=1125899839733759;
inline void Add(ll& x,ll y){
x=(x+y)%M;
}
inline ll Mul(ll x,ll y,ll MOD){
return ((x*y-(ll)(((long double)x*y+0.5)/MOD)*MOD)%MOD+MOD)%MOD;
}
inline ll Pow(ll x,ll y,ll p){
ll Ans=1;
for(;y;y>>=1,x=Mul(x,x,p))if(y&1)Ans=Mul(Ans,x,p);
return Ans;
}
struct Jz{
ll a[3][3];
Jz operator * (Jz b)const{
Jz c;
memset(c.a,0,sizeof(c.a));
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
Add(c.a[i][j],Mul(a[i][k],b.a[k][j],M));
return c;
}
}a,b;
inline Jz Pow(Jz x,ll y){
Jz Ans;
memset(Ans.a,0,sizeof(Ans.a));
Ans.a[1][1]=Ans.a[2][2]=1;
for(;y;y>>=1,x=x*x)if(y&1)Ans=Ans*x;
return Ans;
}
ll n;
int i,j,k,m,p,T;
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld",&n);
memset(a.a,0,sizeof(a.a));a.a[1][1]=1;
b.a[1][1]=b.a[1][2]=b.a[2][1]=1;b.a[2][2]=0;
n=Pow(2,n,M-1)-1;if(n<0)n+=M-1;
a=a*Pow(b,n);
printf("%lld\n",a.a[1][1]);
}
return 0;
}