欧拉降幂, 广义欧拉降幂
ab =
① ab ,b< p
②ab%∮( p )+∮( p ), b >= p
代码(改代码用于解决塔型指数 ——abcd. . .)
#include<bits/stdc++.h>
using namespace std;
#define maxn 101010
#define MOD(a,Mod) a>=Mod?a%Mod+Mod:a//a为指数 Mod为模数。 如果指数大于等于模数 返回a%Mod+Mod, 否则返回a(该部分就是欧拉定理的应用)。
#define ll long long
unordered_map<int,int>mp;
int n,q,l,r;
ll m,w[maxn];
ll qpow(ll a,ll b,ll mod)
{
ll res=1;
while(b)
{
if(b&1)res=MOD(res*a,mod);//同余
a=MOD(a*a,mod);// 同余
b>>=1;
}
return res;
}
ll phi(ll k)// 求欧拉函数部分
{
ll x=k,s=k;
if(mp.count(k))return mp[k];
for(int i=2; i*i<=k; i++)
{
if(k%i==0)s=1ll*s/i*(i-1);
while(k%i==0) k/=i;
}
if(k>1)s=s/k*(k-1);
mp[x]=s;
return s;
}
ll solve(int id,ll mod)// 解决部分
{
if(id==r||mod==1)return MOD(w[id],mod);// mod == 1是剪纸部分, id == r 是边界
return qpow(w[id],solve(id+1,phi(mod)),mod);//递归操作
}
int main()
{
scanf("%d%lld",&n,&m);
for(int i=1; i<=n; i++)scanf("%lld",&w[i]);// W[i] 储存塔型数(从底, 到最后一个指数)
scanf("%lld",&q);
while(q--)
{
scanf("%d%d",&l,&r);// l表示底的编号, r表示最后一个指数的编号
printf("%lld\n",solve(l,m)%m);//结果要取模
}
return 0;
}