推出f(0)=a,f(1)=b,f(2)=a*b,f(3)=a^2*b^3,f(n)=.....
易知a,b的指数幂成fib数列,在利用矩阵求fib时注意利用ph(p)降幂即可。
水一贴~
#include <cstdio> #include <iostream> using namespace std; typedef long long LL; struct Matrix { LL m[2][2]; }d; Matrix Multify(Matrix a,Matrix b,LL mod) { Matrix c; for(int i=0;i<2;i++) for(int j=0;j<2;j++){ c.m[i][j]=0; for(int k=0;k<2;k++) c.m[i][j]+=a.m[i][k]*b.m[k][j]; if(c.m[i][j]>=mod) c.m[i][j]=c.m[i][j]%mod+mod; } return c; } Matrix Power(Matrix a,LL k,LL mod) { Matrix r; for(int i=0;i<2;i++) for(int j=0;j<2;j++) r.m[i][j]=(i==j)?1:0; while(k) { if(k&1) r=Multify(r,a,mod); a=Multify(a,a,mod); k>>=1; } return r; } LL power(LL a,LL b,LL mod) { LL ret=1; while(b) { if(b&1) ret=ret*a%mod; a=a*a%mod; b>>=1; } return ret; } LL phi(LL x) { LL ans=x; for(int i=2;i*i<=x;i++) if(x%i==0){ ans=ans/i*(i-1); while(x%i==0) x/=i; } if(x>1) ans=ans/x*(x-1); return ans; } void Init() { d.m[0][0]=1; d.m[0][1]=1; d.m[1][0]=1; d.m[1][1]=0; } int main() { int cas,T=1; scanf("%d",&cas); Init(); while(cas--) { LL a,b,P,n; scanf("%I64d%I64d%I64d%I64d",&a,&b,&P,&n); LL p=phi(P); Matrix r=Power(d,n-1,p); a=power(a,r.m[1][1],P); b=power(b,r.m[0][1],P); a=a*b%P; printf("Case #%d: %I64d\n",T++,a); } return 0; }