题目: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);
}
}