版权声明:这是蒟蒻的BLOG,神犇转载也要吱一声哦~ https://blog.csdn.net/Dream_Lolita/article/details/89507890
【题目】
lydsy
求
,答案对
取模
【解题思路】
打表可以发现模数是个素数,个位数又是九,所以根号五有二次剩余。
于是就是二次剩余板子,用斐波那契的通项来求就行了。
注意扩域的复数乘法,虚部实际上是
。
【参考代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double db;
const ll mod=1125899839733759ll,inv2=(mod+1)>>1;
namespace Cipolla
{
ll w;
ll mul(ll x,ll y,ll p=mod){return ((x*y-(ll)((db)x/p*y+0.5)*p)%p+p)%p;}
/*ll mul(ll x,ll y,ll p=mod)
{
ll res=0;
for(;y;y>>=1,x=(x+x)%p) if(y&1) res=(res+x)%p;
return res;
}*/
struct cd
{
ll x,y;
cd(ll _x=0,ll _y=0):x(_x),y(_y){}
cd operator *(const cd&A)const{return cd((mul(x,A.x)+mul(mul(y,A.y),w))%mod,(mul(x,A.y)+mul(y,A.x))%mod);}
};
ll ipow(cd x,ll y)
{
cd res=cd(1,0);
for(;y;y>>=1,x=x*x)if(y&1)res=res*x;
return res.x;
}
ll qpow(ll x,ll y,ll p=mod)
{
ll res=1;
for(;y;y>>=1,x=mul(x,x,p))if(y&1)res=mul(res,x,p);
return res;
}
ll calc(ll x,ll p=mod)
{
if(!x) return 0;
ll t=qpow(x,(p-1)>>1,p);
if(t==mod-1) return -1;
for(;;)
{
t=mul(rand()%p,rand()%p,p);w=(mul(t,t)-x+p)%p;
if(qpow(w,(p-1)>>1,p)==p-1) return ipow(cd(t,1),(p+1)>>1);
}
}
}
using namespace Cipolla;
int main()
{
#ifdef Durant_Lee
freopen("BZOJ5118.in","r",stdin);
freopen("BZOJ5118.out","w",stdout);
#endif
srand(2333);
ll sq5,A,B,iv,n,ans,T;
sq5=calc(5);A=mul(sq5+1,inv2);B=mul(sq5-1,inv2);iv=qpow(sq5,mod-2);
//cerr<<sq5<<endl;
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);n=qpow(2,n,mod-1);
ans=mul(iv,(qpow(A,n)-qpow(B,n)+mod)%mod);
printf("%lld\n",ans);
}
return 0;
}