CodeForces - 906D Power Tower(欧拉降幂定理)

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 906D Power Tower(欧拉降幂定理)相关的知识,希望对你有一定的参考价值。

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;
}

 

?
?
?

以上是关于CodeForces - 906D Power Tower(欧拉降幂定理)的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 906D Power Tower <<欧拉降幂

Codeforces 1247D. Power Products

Codeforces1560 D. Make a Power of Two(思维+暴力)

Codeforces 906 D Power Tower

[CodeForces - 1225D]Power Products 数论 分解质因数

CodeForces 907F Power Tower(扩展欧拉定理)