题意
让你求
思路
假设要求,
根据拓展欧拉定理,我们可以得到 ,
接着继续求,还是根据拓展欧拉定理可以得到
当然上面的情况都是建立指数大于 的情况, 对于指数小于
的情况,我们就是直接返回不加
的版本,那么这个判断也太复杂了!
偷学了个小技巧,我们可以修改取模的这个操作,的情况我们就返回
,不然就返回
,这样的话,我们就能保证结果的正确性
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define dd(x) cout << #x << " = " << x << ' '
#define de(x) cout << #x << " = " << x << '\n'
int Mod(ll a, ll b) { return a > b ? a % b + b : a; }
int get_phi(int x) {
int ret = 1;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) {
ret *= (i - 1);
x /= i;
while(x % i == 0) {
ret *= i;
x /= i;
}
}
}
if (x != 1) ret *= (x - 1);
return ret;
}
int kpow(int a, int b, int c) {
int ret = 1;
while(b) {
if (b & 1) {
ret = Mod(1ll * ret * a, c);
}
a = Mod(1ll * a * a, c);
b >>= 1;
}
return ret;
}
int gao(int l, int r, int i, const vector<int>& w, const vector<int>& p) {
// dd(l), de(r);
if (l >= r || p[i] == 1) return Mod(w[l], p[i]);
return kpow(w[l], gao(l + 1, r, i + 1, w, p), p[i]);
}
int main() {
int n, m; cin >> n >> m;
vector<int> w(n);
for (int i = 0; i < n; ++i) cin >> w[i];
int q; cin >> q;
vector<int> p;
p.push_back(m);
// de(0);
while(p.back() != 1) p.push_back(get_phi(p.back()));
// de(1);
// for (int i = 0; i < p.size(); ++i) dd(i), de(p[i]);
while(q--) {
int l, r; cin >> l >> r;
// dd(l), de(r);
l--; r--;
cout << gao(l, r, 0, w, p) % m << '\n';
}
return 0;
}