题目
思路
首先我们考虑暴力的做法
也就是说我们直接用欧拉定理直接暴力做
时间复杂度为\(O(n*m)\)
这个时间复杂度明显是原地爆炸的
但是我们考虑在用欧拉函数的过程中
每一层都会使用到上一层的\(\varphi\)
单独考虑\(\varphi\)的变化过程,很容易发现
\(\varphi(\varphi(m))\le \frac{\varphi(m)}{2}\)
而且 \(\varphi(1)=1\)
我们考虑1个数与取模1再加1,
这不还是1么
所以这样下来总的时间复杂度可以降到\(O(m*log_n)\)
代码
#include<iostream> using namespace std; long long n,mod; long long m; long long l,r; long long a[500005]; long long phi[500005]; long long varphi(long long n) { long long ans=n; for(int i=2;1ll*i*i<=n;i++) { if(n%i==0) { ans=ans/i*(i-1); while(!(n%i)) { n/=i; } } } if(n>1) ans=ans/n*(n-1); return ans; } long long ex_oular(long long x,long long mod) { if(x>=mod) return x=x%mod+mod; else return x; } long long qkpow(long long a,long long b,long long mod) { if(b==0) return 1; if(b==1) return a; long long t=qkpow(a,b/2,mod); t=ex_oular(t*t,mod); if(b%2==1) t=ex_oular(t*a,mod); return t; } long long dfs(long long l,long long r,long long k) { if(l==r||phi[k]==1) { return ex_oular(a[l],phi[k]); } return qkpow(a[l],dfs(l+1,r,k+1),phi[k]); } int main() { ios::sync_with_stdio(false); cin>>n>>mod; phi[0]=mod; for(int i=1;i<=n;i++) phi[i]=varphi(phi[i-1]); for(int i=1;i<=n;i++) cin>>a[i]; cin>>m; for(int i=1;i<=m;i++) { cin>>l>>r; cout<<dfs(l,r,0)%mod<<'\n'; } return 0; }