您的位置:首页 > 其它

[bzoj5118]Fib数列2_费马小定理_矩阵乘法

2018-07-15 23:22 375 查看

Fib数列2 bzoj-5118

题目大意:求Fib($2^n$)。

注释:$1\le n\le 10^{15}$。

想法:开始一看觉得一定是道神题,多好的题面啊?结果...妈的,模数是质数,费马小定理就tm完事了,将fib数列的通项公式列出来然后费马小定理...

最后,附上丑陋的代码... ...(照着郭爷一顿瞎jb敲)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 1125899839733759
typedef long long ll;
inline ll mul(ll x,ll y,ll p)
{
ll ans=0;
while(y)
{
if(y&1) ans=(ans+x)%p;
x=(x+x)%p,y>>=1;
}
return ans;
}
inline ll pow(ll x,ll y,ll p)
{
ll ans=1;
while(y)
{
if(y&1) ans=mul(ans,x,p);
x=mul(x,x,p),y>>=1;
}
return ans;
}
struct data
{
ll v[2][2];
data(){memset(v,0,sizeof(v));}
ll*operator [] (int a){return v[a];}
data operator * (data a)
{
data ans;
int i,j,k;
for(i=0;i<2;i++)
for(k=0;k<2;k++)
for(j=0;j<2;j++)
ans[i][j]=(ans[i][j]+mul(v[i][k],a[k][j],mod))%mod;
return ans;
}
data operator^(ll y)
{
data x=*this,ans;
ans[0][0]=ans[1][1]=1;
while(y)
{
if(y&1)ans=ans*x;
x=x*x,y>>=1;
}
return ans;
}
}A;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll n;
scanf("%lld",&n),n=pow(2,n,mod-1);
A[0][0]=0,A[0][1]=A[1][0]=A[1][1]=1,A=A^n;
printf("%lld\n",A[1][0]);
}
return 0;
}

 小结:好题

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: