链接:
https://ac.nowcoder.com/acm/contest/3002/J
解法:
列出前几天的影响力,可以发现 f(n) = xfib(n-2)*yfib(n-1)*(ab)fib(n)-1,fib(n)就是第n个斐波那契数,答案就是f(n) % (1e9+7)。
由于n很大,在计算指数时可利用矩阵快速幂,由于指数在计算时也很大所以要用欧拉降幂ab ≡ ab%Φ(p) (mod p) 处理。又p为素数,则Φ(p) = p-1,所以在利用快速幂计算时式子为 f(n) = xfib(n-2)%(p-1)*yfib(n-1)%(p-1)*(ab)fib(n)%(p-1)-1。
至此,本题就转化为矩阵快速幂和快速幂的模板题,矩阵快速幂求斐波那契数,快速幂求解最终答案,要注意a是模数倍数的情况,在求解时a先对p取模,再进行计算。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 struct mt{ 5 ll a[3][3]; 6 }; 7 mt t(mt a,mt b,ll mod){ 8 mt res; 9 int i,j,k; 10 for(i=0;i<3;i++){ 11 for(j=0;j<3;j++){ 12 res.a[i][j]=0; 13 for(k=0;k<3;k++){ 14 res.a[i][j]+=a.a[i][k]*b.a[k][j]%mod; 15 res.a[i][j]%=mod; 16 } 17 } 18 } 19 return res; 20 } 21 mt power(mt a,ll b,ll mod){ 22 mt res; 23 int i,j; 24 for(i=0;i<3;i++){ 25 for(j=0;j<3;j++){ 26 res.a[i][j]=0; 27 } 28 } 29 res.a[0][0]=res.a[1][1]=res.a[2][2]=1; 30 31 while(b){ 32 if(b&1)res=t(res,a,mod); 33 b>>=1; 34 a=t(a,a,mod); 35 } 36 return res; 37 } 38 ll feb(ll n,ll mod){ 39 mt temp; 40 int i,j; 41 for(i=0;i<3;i++){ 42 for(j=0;j<3;j++){ 43 temp.a[i][j]=0; 44 } 45 } 46 temp.a[0][1]=temp.a[1][1]=temp.a[1][0]=temp.a[1][2]=1; 47 mt res=power(temp,n-1,mod); 48 return (res.a[0][0]+res.a[0][1])%mod; 49 } 50 51 ll power(ll a,ll b,ll mod){ 52 ll res=1; 53 54 while(b){ 55 if(b&1)res=res*a%mod; 56 b>>=1; 57 a=a*a%mod; 58 } 59 return res; 60 } 61 int main(){ 62 int m=1e9+7; 63 64 int i,j; 65 ll n,x,y,a,b; 66 cin>>n>>x>>y>>a>>b; 67 if(n==1){cout<<x%m;return 0;} 68 if(n==2){cout<<y%m;return 0;} 69 if(x%m==0||y%m==0||a%m==0){cout<<0;return 0;} 70 x%=m; 71 y%=m; 72 73 a=power(a%m,b,m); //这里要注意a对m取模 74 75 cout<<power(x,feb(n-2,m-1),m)*power(y,feb(n-1,m-1),m)%m*power(a%m,feb(n,m-1)-1,m)%m<<endl; 76 77 }