codeforces 906 D Power Tower (欧拉降幂)

题目:http://codeforces.com/problemset/problem/906/D

题意:给数列a[],每次询问a[l]^a[l+1]^...^a[r]%p的值。

思路:欧拉降幂。由于询问较多,用map保存之前算过的欧拉函数值。

代码:

#include
using namespace std;
#define int long long
unordered_mapmp;
int euler_phi(int n){
    if(mp.count(n)) return mp[n];
    int tmp = n;
    int ans = n;
    for(int i=2; i*i<=n; i++) if(n % i == 0){
        ans = ans / i * (i-1);
        while(n % i == 0) n /= i;
    }
    if(n > 1) ans = ans / n * (n-1);
    mp[tmp] = ans;
    return ans;
}
int mod(int a, int p){return a>=p?a%p+p:a;} //注意mod时的处理
int quick_mod(int a, int b, int p){ 
    int sum = 1;
    while(b){
        if(b&1) sum = mod(sum*a, p);
        a = mod(a*a, p); b >>= 1;
    }return sum;
}
int a[100005], n, m, q, l, r;
int solve(int l, int r, int p){
    if(l==r || p==1) return mod(a[l], p);
    return quick_mod(a[l], solve(l+1, r, euler_phi(p)), p);
}
int solve2(int a, int b, int p){ // a^a^a^…^a(b个a) % p
	if(b==0 || p==1) return 1;
	return quick_mod(a, solve2(a, b-1, euler_phi(p)), p);
}
int32_t main(){
    scanf("%lld%lld", &n, &m);
    for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
    scanf("%lld", &q);
    while(q--){
        scanf("%lld%lld", &l, &r);
        printf("%lld\n", solve(l, r, m)%m);
    }
}

 

你可能感兴趣的:(数论)