[數學][歐拉降冪定理]Exponial
阿新 • • 發佈:2018-10-07
return pow long ret 可能 sca php 怎麽 lse
當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代碼:
Exponial
題目
http://exam.upc.edu.cn/problem.php?cid=1512&pid=4
歐拉降冪定理:當b>phi(p)時,有a^b%p = a^(b%phi(p)+phi(p))%p
這題做的難受....看到題目我就猜到肯定用到歐拉降冪,然後就毫無目的地找規律。然後發現不同地取歐拉函數會變成0,然後內心毫無波動.....可能不怎麽會遞歸
思路:當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)
從1e9遞歸到5很慢,但當p=1時,可以直接返回f(n)%p=0而不用遞歸到下一層;
AC代碼:
#include <cstdio> typedef long long ll; ll phi(ll x){ ll res=x; for(ll 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; } ll qpow(ll a,ll n,ll mod){ ll res=1; while(n){ if(n&1){ res*=a; res%=mod; } n>>=1; a=(a*a)%mod; } return res; } 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); ll tem=phi(m); return qpow(n,solve(n-1,tem)+tem,m); } int main() { //printf("%lld\n",phi(1000000)); ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF){ printf("%lld\n",solve(n,m)); } return 0; }
好久沒寫博客.....自己太菜要努力鴨
[數學][歐拉降冪定理]Exponial