• CodeForces


    Power Tower

     CodeForces - 906D 

    题目大意:有N个数字,然后给你q个区间,要你求每一个区间中所有的数字从左到右依次垒起来的次方的幂对m取模之后的数字是多少。

    用到一个新知识,欧拉降幂定理

    记住公式 $LARGE n^x equiv n^{varphi(m) + x mod varphi(m)}(mod m)​$这个式子当且仅当x>φ(m)时满足。那么就可以递归求解了。

    暂时不太明白怎么证明

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #define maxn 100010
    #define Mod(a,b) a<b?a:a%b+b
    using namespace std;
    long long n,m,a[maxn];
    map<long long,long long>p;
    long long qread(){
        long long i=0,j=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
        while(ch<='9'&&ch>='0')i=i*10+ch-'0',ch=getchar();
        return i*j;
    }
    long long Pow(long long x,long long y,long long mod){
        long long res=1;
        while(y){
            if(y&1)res=Mod(res*x,mod);
            x=Mod(x*x,mod);
            y>>=1;
        }
        return res;
    }
    long long phi(long long k){
        long long s=k,x=k;
        if(p[k])return p[k];
        for(long long i=2;i*i<=k;i++){
            if(k%i==0)s=s/i*(i-1);
            while(k%i==0)k/=i;
        }
        if(k>1)s=s/k*(k-1);
        p[x]=s;return s;
    }
    long long solve(int l,int r,long long mod){
        if(l==r||mod==1)return Mod(a[l],mod);
        return Pow(a[l],solve(l+1,r,phi(mod)),mod);
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        n=qread();m=qread();
        for(int i=1;i<=n;i++)a[i]=qread();
        int Q;scanf("%d",&Q);
        int l,r;
        while(Q--){
            scanf("%d%d",&l,&r);
            cout<<solve(l,r,m)%m<<endl;
        }
        return 0;
    }



  • 相关阅读:
    45.如何优雅的删除一张大表?
    13.安装上传和下载文件
    12.yum install 和yum localinstall区别
    7.Mysql之MGR环境搭建
    mod运算
    取整
    同余式
    Windows下的重定向
    C语言求正负余数
    复利计算公式
  • 原文地址:https://www.cnblogs.com/thmyl/p/8276177.html
Copyright © 2020-2023  润新知