Codeforces 906D(尤拉降冪定理? + 唯一分解定理)
阿新 • • 發佈:2018-12-24
莫名其妙的尤拉降冪定理,網上也找不到證明和解釋,只有這個部落格,但是神奇的可以ac,不知道快速冪為什麼寫成這個樣子,正常的快速冪還要wa,覺得很奇怪,真的是我太菜了。。。
剛剛突然想明白了快速冪為什麼寫成這個樣子。。。剛才自己好傻還想了半天,寫成這個樣就是普通的快速冪,不過是符合題目要求而已。。。(將一個數的次方換成尤拉降冪定理之後的形式)φ = 1 的時候也很好理解,此時等號右邊的平方是確定值即 1 ,此時遞迴可以結束,返回值為L//程式碼應該是正確的,雖然沒法理解,但是可以記錄下來當模板使用出處 : 部落格部落格中的程式碼:其中有一段程式碼:#include<bits/stdc++.h> #define Mod(a,b) a<b?a:a%b+b //重定義取模,按照尤拉定理的條件 #define LL long long #define N 100010 using namespace std; LL n,q,mod,a[N]; map<LL,LL> mp; LL qpow(LL x,LL n,LL mod) { LL res=1; while(n) { if (n&1) res=Mod(res*x,mod),n--; x=Mod(x*x,mod); n>>=1; } return res; } LL phi(LL k) { LL i,s=k,x=k; if (mp.count(k)) return mp[x]; //記憶化儲存 for(i = 2;i * i <= k; i++) { if(k % i == 0) s = s / i * (i - 1); while(k % i == 0) k /= i; } if(k > 1) s = s / k * (k - 1); mp[x]=s; return s; } LL solve(LL l,LL r,LL mod) { if (l==r||mod==1) return Mod(a[l],mod); //如果到右端點或者φ值等於1,那麼直接返回當前數字 return qpow(a[l],solve(l+1,r,phi(mod)),mod); //否則指數為[l+1,r]區間的結果 } int main() { scanf("%lld%lld",&n,&mod); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); scanf("%lld",&q); while(q--) { int L,R; scanf("%d%d",&L,&R); printf("%lld\n",solve(L,R,mod)%mod); //對mod取模,因為qpow內部是用Mod(a,b)取模 } return 0; }
返回值是尤拉函式值,一開始有點懵,仔細一看就是唯一分解定理將一個數分解,各種質因子,然後運用尤拉函式求解方式φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk),其中p1、p2…pk為n的所有素因子,可以求得尤拉函式值,值得學習。。上面的程式碼就當模板用吧先。。LL phi(LL k) { LL i,s=k,x=k; if (mp.count(k)) return mp[x]; //記憶化儲存 for(i = 2;i * i <= k; i++) { if(k % i == 0) s = s / i * (i - 1); while(k % i == 0) k /= i; } if(k > 1) s = s / k * (k - 1); mp[x]=s; return s; }