http://acm.hdu.edu.cn/showproblem.php?pid=2814
1 17 18446744073709551615 1998 139
Case 1: 120
对于A^B%C 有一个公式 即
A^x = A^(x % Phi(C) + Phi(C)) (mod C)
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define max 400 int quick_mod(int a,unsigned long long b, int c)//快速幂 { int ans=1; a=a%c; while(b>0) { if (b%2==1) ans=(ans*a)%c; b=b/2; a=(a*a)%c; } return ans; } int eular(int n) //欧拉函数 { int ret=1,i; for (i=2; i*i<=n; i++) { if (n%i==0) { n/=i,ret*=i-1; while (n%i==0) n/=i,ret*=i; } } if (n>1) ret*=n-1; return ret; } unsigned long long a,b,n; int c; int data1[9003]; int data2[9003]; int g[9003]; int len,len_c,len_e; int main() { int T,tt=0; scanf("%d",&T); while(T--) { scanf("%I64d%I64d%I64d%d",&a,&b,&n,&c); if(c==1) { printf("Case %d: 0\n",++tt); continue; } data1[0]=0,data1[1]=1; for(int i=2;; i++) { data1[i]=(data1[i-1]+data1[i-2])%c; if(data1[i]==1&&data1[i-1]==0) { len=i-1; break; } } int o=eular(c); if(o==1) len_c=0; else { data2[0]=0,data2[1]=1; for(int i=2;;i++) { data2[i]=(data2[i-1]+data2[i-2])%o; if(data2[i]==1&&data2[i-1]==0) { len_c=i-1; break; } } } int n1=quick_mod(a%len,b,len); g[1]=data1[n1]; int mi_zhi_shu; int n2; if(len_c==0) mi_zhi_shu=0; else { n2=quick_mod(a%len_c,b,len_c); mi_zhi_shu=data2[n2]; } int x=quick_mod(mi_zhi_shu,n-1,o); x+=o; x=quick_mod(g[1],x,c); if(n==1) printf("Case %d: %d\n",++tt,g[1]); else printf("Case %d: %d\n",++tt,x); } return 0; }解法二: 在将n从1~max列举出来,在找循环节,陈老师是这么做的。
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define max 400 int quick_mod(int a,unsigned long long b, int c)//快速幂 { int ans=1; a=a%c; while(b>0) { if (b%2==1) ans=(ans*a)%c; b=b/2; a=(a*a)%c; } return ans; } int eular(int n) //欧拉函数 { int ret=1,i; for (i=2; i*i<=n; i++) { if (n%i==0) { n/=i,ret*=i-1; while (n%i==0) n/=i,ret*=i; } } if (n>1) ret*=n-1; return ret; } unsigned long long a,b,n; int c; int data1[9003]; int data2[9003]; int g[9003]; int len,len_c,len_e; int main() { int T,tt=0; scanf("%d",&T); while(T--) { scanf("%I64d%I64d%I64d%d",&a,&b,&n,&c); if(c==1) { printf("Case %d: 0\n",++tt); continue; } data1[0]=0,data1[1]=1; for(int i=2;; i++) { data1[i]=(data1[i-1]+data1[i-2])%c; if(data1[i]==1&&data1[i-1]==0) { len=i-1; break; } } int o=eular(c); if(o==1) len_c=0; else { data2[0]=0,data2[1]=1; for(int i=2;;i++) { data2[i]=(data2[i-1]+data2[i-2])%o; if(data2[i]==1&&data2[i-1]==0) { len_c=i-1; break; } } } int n1=quick_mod(a%len,b,len); g[1]=data1[n1]; int mi_zhi_shu; int n2; if(len_c==0) mi_zhi_shu=0; else { n2=quick_mod(a%len_c,b,len_c); mi_zhi_shu=data2[n2]; } mi_zhi_shu+=o; for(int i=2;i<=max;i++) g[i]=quick_mod(g[i-1]%c,mi_zhi_shu,c); for(int i=max-1;i>=1;i--) { if(g[i]==g[max]) { len_e=max-i; break; } } int tmp=n%len_e; if(n>=len_e) { while(tmp+len_e<max) tmp=tmp+len_e; } if(n<len_e) tmp=n; if(n==1) printf("Case %d: %d\n",++tt,g[1]); else printf("Case %d: %d\n",++tt,g[tmp]); } return 0; }