习题:Power Tower(欧拉定理)

时间秒杀一切 提交于 2019-12-05 11:29:49

题目

传送门

思路

首先我们考虑暴力的做法

也就是说我们直接用欧拉定理直接暴力做

时间复杂度为\(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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!