HDU 3221Brute-force Algorithm(降幂公式 神似hdu4549)
33 4 10 34 5 13 53 2 19 100
Case #1: 2Case #2: 11Case #3: 12
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<cmath>using namespace std;__int64 mo,phi;__int64 ret[2][2],tmp[2][2],p[2][2];__int64 n;void init() //初始化{ ret[0][0]=1; ret[0][1]=1; ret[1][0]=1; ret[1][1]=0; p[0][0]=1; p[0][1]=1; p[1][0]=1; p[1][1]=0;}void cal1() //!(n&1){ int i,j,k; for(i=0;i<2;i++) for(j=0;j<2;j++) { tmp[i][j]=p[i][j]; p[i][j]=0; } for(i=0;i<2;i++) for(j=0;j<2;j++) for(k=0;k<2;k++) { p[i][j]=p[i][j]+tmp[i][k]*tmp[k][j]; if(p[i][j]>=phi) p[i][j]=p[i][j]%phi+phi; }}void cal2() //n&1{ int i,j,k; for(i=0;i<2;i++) for(j=0;j<2;j++) { tmp[i][j]=ret[i][j]; ret[i][j]=0; } for(i=0;i<2;i++) for(j=0;j<2;j++) for(k=0;k<2;k++) { ret[i][j]=ret[i][j]+tmp[i][k]*p[k][j]; if(ret[i][j]>=phi) ret[i][j]=ret[i][j]%phi+phi; }}void fastmi() //矩阵的快速幂{ init(); n-=3; while(n) { if(n&1) cal2(); cal1(); n>>=1; }}__int64 pow(__int64 base,__int64 p) //快速幂{ __int64 ans=1; while(p) { if(p&1) ans=(ans*base)%mo; base=(base*base)%mo; p>>=1; } return ans;}__int64 geteuler(__int64 n){ __int64 m=sqrt(n+0.5),ans=n,i; for(i=2;i<=m;i++) if(n%i==0) { ans=ans/i*(i-1); while(n%i==0) n/=i; } if(n>1) ans=ans/n*(n-1); return ans;}int main(){ __int64 a,b; int i,tes; scanf("%d",&tes); for(i=1;i<=tes;i++) { scanf("%I64d%I64d%I64d%I64d",&a,&b,&mo,&n); n--; phi=geteuler(mo); //得到欧拉值 __int64 ans1,ans2,res1,res2; if(n==0) ans1=1,ans2=0; else if(n==1) ans1=0,ans2=1; else if(n==2) ans1=1,ans2=1; else { fastmi(); ans2=(ret[0][0]+ret[0][1]); //b的次数 ans1=(ret[1][0]+ret[1][1]); //a的次数 } //printf("%I64d %I64d\n",ans1,ans2); if(ans1>=phi) ans1=ans1%phi+phi; if(ans2>=phi) ans2=ans2%phi+phi; res1=pow(a,ans1); res2=pow(b,ans2); __int64 res=(res1*res2)%mo; printf("Case #%d: %I64d\n",i,res); } return 0;}//0MS