今天摸鱼看到一道题:
这不就快速幂裸题吗??
然后一看数据范围:
???这个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 }