习题:Power Tower(欧拉定理)
题目
思路
首先我们考虑暴力的做法
也就是说我们直接用欧拉定理直接暴力做
时间复杂度为\(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;
}

浙公网安备 33010602011771号