bzoj5118: Fib数列2(费马小定理+矩阵快速幂)
Posted Sakits
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj5118: Fib数列2(费马小定理+矩阵快速幂)相关的知识,希望对你有一定的参考价值。
题目大意:求$fib(2^n)$
就是求fib矩阵的(2^n)次方%p,p是质数,根据费马小定理有
注意因为模数比较大会爆LL,得写快速乘法...
#include<bits/stdc++.h> #define ll long long #define MOD(x) ((x)>=mod?(x-mod):(x)) using namespace std; const int maxn=500010; const ll mod=1125899839733759; struct mtx{ll mp[2][2];mtx(){memset(mp, 0, sizeof(mp));}}ans, base; ll n, T; inline ll mul(ll a, ll b, ll mod) { ll ans=0; a%=mod; for(;b;b>>=1, a=MOD(a+a)) if(b&1) ans=MOD(ans+a); return ans; } mtx operator*(mtx a, mtx b) { mtx c; for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) c.mp[i][j]=MOD(c.mp[i][j]+mul(a.mp[i][k], b.mp[k][j], mod)); return c; } inline ll power(ll a, ll b, ll mod) { ll ans=1; for(;b;b>>=1, a=mul(a, a, mod)) if(b&1) ans=mul(ans, a, mod); return ans; } inline ll mtx_power(ll b) { if(!b) return 0; for(;b;b>>=1, base=base*base) if(b&1) ans=ans*base; return ans.mp[1][0]; } int main() { scanf("%lld", &T); while(T--) { scanf("%lld", &n); ll t=power(2, n, mod-1); base.mp[0][0]=base.mp[0][1]=base.mp[1][0]=1; base.mp[1][1]=0; ans.mp[0][0]=ans.mp[1][1]=1; ans.mp[1][0]=ans.mp[0][1]=0; printf("%lld\\n", mtx_power(t)); } }
以上是关于bzoj5118: Fib数列2(费马小定理+矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章