習題:Product Oriented Recurrence(矩陣快速冪)
阿新 • • 發佈:2020-08-24
題目
思路
我們將乘法轉換成冪的加法即可
注意指數取模是取模\(\phi(1e9+7)\)
其實就是\(1e9+6\)
程式碼
#include<iostream> #include<cstring> using namespace std; const int mod=1e9+6; long long n,f1,f2,f3,c; struct mat { int n,m; long long a[6][6]; mat() { n=m=0; memset(a,0,sizeof(a)); } friend mat operator * (const mat &a,const mat &b) { mat c; c.n=a.n; c.m=b.m; for(int i=1;i<=a.n;i++) for(int k=1;k<=a.m;k++) for(int j=1;j<=b.m;j++) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod; return c; } }bas[5],acc[5]; long long qkpow(long long a,long long b) { if(b==0) return 1; if(b==1) return a%(mod+1); long long t=qkpow(a,b/2); t=t*t%(mod+1); if(b%2==1) t=t*a%(mod+1); return t; } mat qkpow(mat a,long long b) { if(b==1) return a; mat t=qkpow(a,b/2); t=t*t; if(b%2==1) t=t*a; return t; } int main() { cin>>n>>f1>>f2>>f3>>c; bas[1].n=bas[2].n=bas[3].n=3; bas[1].m=bas[2].m=bas[3].m=1; bas[1].a[1][1]=bas[2].a[2][1]=bas[3].a[3][1]=1; acc[1].n=acc[1].m=3; acc[1].a[1][2]=acc[1].a[2][3]=acc[1].a[3][1]=acc[1].a[3][2]=acc[1].a[3][3]=1; acc[2]=acc[1]; acc[3]=acc[1]; bas[4].n=5; bas[4].m=1; bas[4].a[4][1]=bas[4].a[5][1]=2; acc[4].n=acc[4].m=5; acc[4].a[1][2]=acc[4].a[2][3]=acc[4].a[3][1]=acc[4].a[3][2]=acc[4].a[3][3]=acc[4].a[3][4]=acc[4].a[4][4]=acc[4].a[4][5]=acc[4].a[5][5]=1; bas[1]=qkpow(acc[1],n-1)*bas[1]; bas[2]=qkpow(acc[2],n-1)*bas[2]; bas[3]=qkpow(acc[3],n-1)*bas[3]; bas[4]=qkpow(acc[4],n-1)*bas[4]; /*for(int i=1;i<=4;i++) cout<<bas[i].a[1][1]<<' '; cout<<endl;*/ cout<<qkpow(f1,bas[1].a[1][1])*qkpow(f2,bas[2].a[1][1])%(mod+1)*qkpow(f3,bas[3].a[1][1])%(mod+1)*qkpow(c,bas[4].a[1][1])%(mod+1); return 0; } /* 100 010 001 111 1 2 2 -> 3 3 4 */ /* {2x-6}->{2(x+1)-6} {2x-1}->{2x-6+2} 2:0 0 3:0 -> 2 4:2 -> 4 1 :0 01000 2 :0 00100 3 :0 11110 d4 :2 00011 bas:2 00001 */