1. 程式人生 > >拓展歐拉定理及其應用

拓展歐拉定理及其應用

using char ++ amp color int result ace name

回顧一下上節的歐拉定理:

其化簡的形式為:

a^φ(m)≡1(mod m)

就有:

a^x≡a^(x%φ(m))≡a^(x%φ(m)+φ(m))(mod m)

看一道題:

Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000000000,1<=B<=10^1000000)

這個B是非常大的一個指數,那麽冪就更大了,需要降冪

若gcd(a,c)=1,那麽使用歐拉定理即可:a^b≡a^(b%φ(m))(mod m)

若gcd(a,m)>1,且b>φ(m),則有“求冪大法”

a^b≡a^(b%φ(m)+φ(m))(mod m)

這就是剛才的那個式子,(當b<=φ(m)時直接用快速冪即可)

 1 //A^B %C=A^( B%phi(C)+phi(C) ) %C
 2 #include<cstdio>
 3 using namespace std;
 4 int c;
 5 long long a,nb;
 6 char tb[1000005];
 7 int phi(int x)
 8 {
 9     int ans=x;
10     for(int i=2;i*i<=x;i++)
11     {
12         if(x%i==0)
13         {
14             ans=(ans/i)*(i-1
); 15 while(x%i==0) x=x/i; 16 } 17 } 18 if(x!=1) ans=(ans/x)*(x-1); 19 return ans; 20 } 21 long long qpow(long long m,long long n,long long k) 22 { 23 long long ans=1; 24 while(n!=0) 25 { 26 if(n&1) ans=(ans*m)%k; 27 n=(n>>1); 28 m=(m*m)%k;
29 } 30 return ans; 31 } 32 int main() 33 { 34 while(scanf("%I64d%s%d",&a,tb,&c)!=EOF) 35 { 36 int PHI=phi(c); 37 long long res=0; 38 for(int i=0;tb[i];i++) 39 { 40 res=(res*10+tb[i]-0); 41 if(res>c) break; 42 } 43 if(res<=PHI) printf("%I64d\n",qpow(a,res,c)); 44 else 45 { 46 res=0; 47 for(int i=0;tb[i];i++) res=(res*10+tb[i]-0)%PHI; 48 printf("%I64d\n",qpow(a,res+PHI,c)); 49 } 50 } 51 return 0; 52 }

拓展歐拉定理,肯定試用範圍最廣嘍

拓展歐拉定理及其應用