欧拉降幂
看了那么多欧拉降幂的博客,都把理论说的通篇大论的,从费马定理什么的开始讲,但自从组队后,数论的东西都抛之脑后了,还好碰到一位良心博主,索性抛弃证明,直接给出方法和结论,甚是爽快。所以,我写个小笔记记录一蛤。
欧拉降幂,在指数爆炸的时候,不得不将指数降降,这个降法,就是将指数取模于该模的欧拉数再加上该模的欧拉数。通俗讲就是,碰到a^b%c=a^(b%phi(c)+phi(c))%c,b>=phi(c);看到这个就不用管这个公式怎么来的了,(因为看了一会儿,看的头皮发麻)生命诚可贵,发量数不多。不管1加1是几,就拿例题过过手了。
博客链接:https://blog.csdn.net/chenkunn/article/details/83792306
样题:https://vjudge.net/problem/FZU-1759
ac代码:
#include<queue> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #include<stack> #define MIN(x,y) ((x)<(y)?(x):(y)) #define MAX(x,y) ((x)>(y)?(x):(y)) using namespace std; typedef long long ll; ll phi(ll n) { ll rec=n; for(int i=2;i*i<=n;i++) { if(n%i==0) { rec=rec-rec/i;//这里看到一个秒懂的注释记录一下:同于rec*(1-1/i) while(n%i==0) n/=i; } } if(n>1) rec=rec-rec/n; return rec; } ll Pow(ll a,ll b,ll mod) { ll rec=1; while(b) { if(b&1) rec=rec*a%mod; a=a*a%mod; b>>=1; } return rec; } int main() { ll a,mod; string b; while(cin>>a>>b>>mod) { ll k=phi(mod); ll len=b.size(); ll d=0; for(int i=0;i<len;i++) d=(d*10+b[i]-'0')%k; d+=k; cout<<Pow(a,d,mod)<<endl; } return 0; }