矩陣快速冪模板(過載運算子)
阿新 • • 發佈:2018-11-08
題意
求斐波那契數列第n項,n<=1e18
solution
1.顯然O(n)遞推肯定不行
2.所以我們考慮用矩陣快速冪加速遞推
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<cmath> #include<cstdlib> #include<ctime> using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f; const ll p=100000007; inline ll read(){ char ch=' ';ll f=1;ll x=0; while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*f; } struct Matrix { ll x,y; ll m[3][3]; }a,b,c; Matrix operator *(Matrix a,Matrix b) { ll n,m,q; n=a.x;m=a.y; q=b.y; Matrix tmp; tmp.x=n;tmp.y=q; memset(tmp.m,0,sizeof(tmp.m)); for(ll i=1;i<=n;i++) { for(ll j=1;j<=m;j++) { for(ll k=1;k<=q;k++) { tmp.m[i][j]+=a.m[i][k]*b.m[k][j]; tmp.m[i][j]%=p; } } } return tmp; } Matrix mul(Matrix x,ll y) { Matrix ret; ret.m[1][1]=1; ret.m[1][2]=0; ret.m[2][1]=0; ret.m[2][2]=1; ret.x=2;ret.y=2; while(y) { if(y&1) { ret=ret*x; } x=x*x; y=y>>1; } return ret; } int main() { ll n=read(); a.m[1][1]=1; a.m[1][2]=1; a.m[2][1]=1; a.m[2][2]=0; a.x=2;a.y=2; b.m[1][1]=1; b.m[1][2]=1; b.x=1;b.y=2; c=mul(a,n); b=b*c; cout<<b.m[1][1]<<endl; return 0; }