【数论】——欧拉定理

今天摸鱼看到一道题:

 这不就快速幂裸题吗??

然后一看数据范围:

 ???这个b的范围吓到我了

经过一番学习,原来这道题考察的是:

欧拉定理&扩展欧拉定理

证明略过,直接上结论:

 

 (图源OI wiki)

那么这道题就是先处理出欧拉函数,再根据扩展欧拉求解即可。注意b要边输入边取模

欧拉函数的处理方式:

  类似于线性筛素数,看标程即可,很好理解。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll M=1e6+10;
 5 ll ans[M],phi[M];
 6 ll cnt;
 7 ll m,a,b;
 8 void Eulersieve(){
 9     phi[1]=1;
10     for(ll i=2;i<=m;i++){
11         if(!phi[i]){
12             for(ll j=i;j<=m;j+=i){
13                 if(!phi[j]) phi[j]=j;
14                 phi[j]=phi[j]/i*(i-1);
15             }
16         }
17     }
18 } 
19 ll read(){
20     ll x=0,f=1;
21     char c=getchar();
22     while(!isdigit(c)){
23         if(c=='-') f=-1;
24         c=getchar();
25     } 
26     while(isdigit(c)){
27         x=x*10+c-'0';
28         c=getchar();
29     }
30     return x*f;
31 }
32 ll getb(){
33     ll x=0,flag=0;
34     char c=getchar();
35     while(!isdigit(c)){
36         c=getchar();
37     }
38     while(isdigit(c)){
39         x=(x*10+c-'0');
40         if(x>=phi[m]){
41             flag=1;
42             x%=phi[m];
43         }
44         c=getchar();
45     }
46     if(x>=phi[m]){
47         flag=1;
48         x%=phi[m];
49     }
50     return flag==1?x+phi[m]:x;
51 }
52 ll qp(ll n,ll p){
53     ll res=n,ans=1;
54     while(p){
55         if(p&1){
56             ans=(res*ans)%m;
57         }
58         res=(res*res)%m;
59         p>>=1;
60     }
61     return ans;
62 }
63 int main(){
64     a=read();
65     m=read();
66     Eulersieve();
67     b=getb();
68     printf("%lld",qp(a,b));
69     return 0;    
70 }

猜你喜欢

转载自www.cnblogs.com/Nelson992770019/p/11517149.html