数学:拓展欧拉定理

回顾一下上节的欧拉定理:

其化简的形式为:

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
",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
",qpow(a,res+PHI,c));
49         }
50     }
51     return 0;
52 }

拓展欧拉定理,肯定试用范围最广喽

原文地址:https://www.cnblogs.com/aininot260/p/9486325.html