2019ICPC(南京) - super_log(欧拉降幂)
生活随笔
收集整理的這篇文章主要介紹了
2019ICPC(南京) - super_log(欧拉降幂)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:求(a^a^a^a....^a)%mod,其中有b個a
題目分析:一道數論題,被我們做成了模擬題。。首先因為涉及到指數并且指數都還比較大,所以需要知道一個降冪公式:
我們需要明白這個公式的第一行是狹義歐拉降冪,第二行和第三行是廣義歐拉降冪,所以我們可以直接通過廣義公式就可以不用考慮互質的情況了,特別需要注意一下廣義的的公式中,單純的取模和取模后在加歐拉函數值,最后得出的結果是完全不同的,所以我們一定要根據條件嚴格判斷,可以在快速冪中進行判斷取模加模,也可以在外面自己分類討論然最后返回快速冪,因為第一層是要對mod取模,第二層是對p[mod]取模,第三層是要對p[p[mod]]取模,每次取模的數值都是上一層取模數的歐拉函數值,所以我們可以遞歸處理,有一個隱藏的剪枝可以大大減少遞歸時間,因為一個數的歐拉函數肯定是小于它本身的,所以logn層遞歸后模會變為1(我不會證明。。太菜了),又因為所有數對1取模答案都是0,所以到此為止就可以直接返回答案了,最后就是都記得開longlong,因為中間值如果mod取1e6,那么1e6*1e6就爆掉int了,最后導致的要么WA掉,要么因為沒辦法logn的時間就退出遞歸,就會T掉,上代碼:
#include<iostream> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<cstdio> using namespace std; typedef long long LL;const int N=1e6+100;LL pow(LL a,LL b,LL mod) {LL ans=1;while(b){if(b&1){ans=(ans*a)%mod;}b>>=1;a=(a*a)%mod;}return ans; }LL p[N];void phi_table()//網上隨便百度的歐拉函數表。。一看格式就知道不是我寫的代碼 {for(int i=2;i<N;i++)p[i]=0;p[1]=1;for(int i=2;i<N;i++)if(!p[i])for(int j=i;j<N;j+=i){if(!p[j])p[j]=j;p[j]=p[j]/i*(i-1);} }LL solve(LL a,LL b,LL mod)//solve函數計算的是a的第b次乘方模mod后的結果 {if(mod==1)//任何數對1取模結果都為0,到此返回即可 return 0;if(b==0)//任何數的0次方等于1,直接返回即可 return 1%mod;LL temp=solve(a,b-1,p[mod]);//計算出a頭頂上的所有乘方的結果儲存到temp中 if(temp&&temp<p[mod])//按照廣義歐拉降冪分類討論一下,注意討論一下答案等于0時return pow(a,temp,mod);else//因為原先答案必不可能等于0,所以當上面返回的答案為0時,將其視為模即可 return pow(a,temp%p[mod]+p[mod],mod); }int main() {int w;cin>>w;phi_table();while(w--){LL a,b,mod;scanf("%lld%lld%lld",&a,&b,&mod);printf("%lld\n",solve(a,b,mod)%mod);}return 0; }?
總結
以上是生活随笔為你收集整理的2019ICPC(南京) - super_log(欧拉降幂)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019ICPC(银川) - Take
- 下一篇: 2019ICPC(南京) - Holy