




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).
标签:col 题目 struct ret out pre top can positive
2 42
2
欧拉降幂定理:当b>phi(p)时,有a^b%p=a^(b%phi(p)+phi(p))%p
思路:当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> long long n,m; long long mod; long long phi(long long x) { long long res=x; for(long long i=2; i*i<=x; ++i) { if(x%i==0) { res=res-res/i; while(x%i==0) x/=i; } } if(x>1) res=res-res/x; return res; } long long qpow(long long a,long long n,long long mod) { long long res=1; while(n) { if(n&1) { res*=a; res%=mod; } n>>=1; a=(a*a)%mod; } return res; } long long solve(long long n,long long 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); long long tem=phi(m); return qpow(n,solve(n-1,tem)+tem,m); } int main() { while(~scanf("%lld%lld",&n,&m)) { printf("%lld\n",solve(n,m)); } return 0; }
标签:col 题目 struct ret out pre top can positive
原文地址:https://www.cnblogs.com/lllxq/p/9748184.html