题目描述
![](http://exam.upc.edu.cn/upload/image/20161024/20161024085356_84662.jpg)
![](http://exam.upc.edu.cn/upload/image/20161024/20161024085231_24756.jpg)
![](http://exam.upc.edu.cn/upload/image/20161024/20161024085255_35569.jpg)
![](http://exam.upc.edu.cn/upload/image/20161024/20161024085313_20431.jpg)
![](http://exam.upc.edu.cn/upload/image/20161024/20161024085329_92138.jpg)
Since the exponials are really big, they can be a bit unwieldy to work with. Therefore we would like you to write a program which computes exponial(n) mod m (the remainder of exponial(n) when dividing by m).
输入
The input consists of two integers n (1 ≤ n ≤ 109 ) and m (1 ≤ m ≤ 109 ).
输出
Output a single integer, the value of exponial(n) mod m.
样例输入
2 42
样例输出
2
欧拉降幂定理:当b>phi(p)时,有a^b%p=a^(b%phi(p)+phi(p))%p
https://blog.csdn.net/weixin_38686780/article/details/81272848
思路:当n>=6时,欧拉降幂定理一定适用,因为f(5)>1e9,也就是一定有欧拉降幂定理的b>phi(p)这个条件,所以f(n)%p=n^f(n-1)%p=n^(f(n-1)%phi(p)+phi(p))%p;再递归地求f(n-1)%phi(p)
当n<=5时,f(n)%p=n^f(n-1)%p,因为不一定有f(n-1)>phi(p)成立,所以不能用欧拉降幂定理求,直接手动求出f(n)%p即可;
从1e9递归到5很慢,但当p=1时,可以直接返回f(n)%p=0而不用递归到下一层;
AC代码:
#include <cstdio> typedef long long ll; ll phi(ll x){ ll ret=x; for(ll i=2;i*i<=x;++i){ if(x%i==0){ ret=ret-ret/i; while(x%i==0) x/=i; } } if(x>1) ret=ret-ret/x; return ret; } ll qpow(ll a,ll b,ll mod){ ll ret=1; while(b){ if(b&1) ret=ret*a%mod; a=a*a%mod; b>>=1; } return ret; } ll solve(ll n,ll m){ if(m==1) return 0; if(n==1) return 1; else if(n==2) return 2%m; else if(n==3) return 9%m; else if(n==4) return qpow(4,9,m); else if(n==5) return qpow(5,262144,m);//可以舍去,不知道为啥 ll tem=phi(m); return qpow(n,solve(n-1,tem)+tem,m); } int main() { ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF){ printf("%lld ",solve(n,m)); } return 0; }