码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-01-12 17:08:48      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:nbsp   return   map   codeforce   out   gpo   color   iostream   pos   

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(欧拉降幂定理)

标签:nbsp   return   map   codeforce   out   gpo   color   iostream   pos   

原文地址:https://www.cnblogs.com/thmyl/p/8276177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!