標籤:bit bsp 規則 name 快速冪 mes 處理 scanf ret
題意
給定n個數,q次詢問,每次輸出[l,r]區間的超級冪,對m模數。
思路
超級冪問題就想到用歐拉降冪來處理
歐拉降冪公式:$a^b \% m=a^{b\%\varphi (m)+\varphi(m)}\%m,(b>\varphi(m))$
本題用遞迴處理歐拉降冪,在$logm$次降冪後$\varphi(m)=1$,然後回溯時用快速冪進行計算,總的複雜度大約是$log^{2}m$
$w_0^{w_1^{w_2^{w_3^{...}}}}\% m = w_0^{[w_1^{w_2^{w_3^{...}}}\%\varphi(m)+\varphi(m)]}\%m$
代碼
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+7; 4 map<int,int> euler; 5 long long w[maxn]; 6 int phi(int n) 7 { 8 int now=n; 9 int ret=n;10 if(euler.count(now)) return euler[now];//記憶化11 for(int i=2;i<=sqrt(n);i++)12 {13 if(n%i==0)14 {15 ret=ret/i*(i-1);16 while(n%i==0)17 n/=i;18 }19 }20 if(n>1)21 ret=ret/n*(n-1);22 euler[now]=ret;23 return ret;24 }25 long long MOD(long long n,int mod)//符合歐拉降冪規則的模數26 {27 return n<mod?n:(n%mod+mod);28 }29 long long quick_mod(long long base,long long p,int mod)30 {31 long long ret=1;32 do{33 if(p&1)34 ret=MOD(base*ret,mod);35 base=MOD(base*base,mod);36 }while(p>>=1);37 return ret;38 }39 long long solve(int l,int r,int mod)40 {41 if(l==r||mod==1) return MOD(w[l],mod);42 return quick_mod(w[l],solve(l+1,r,phi(mod)),mod);43 }44 int main()45 {46 int n,mod;47 scanf("%d%d",&n,&mod);48 for(int i=1;i<=n;i++)49 scanf("%lld",&w[i]);50 int q;51 scanf("%d",&q);52 while(q--)53 {54 int l,r;55 scanf("%d%d",&l,&r);56 long long ans=solve(l,r,mod)%mod;57 printf("%lld\n",ans);58 }59 }
CodeForces 906D Power Tower <<歐拉降冪