a ^ a ^ a ^ … ^ b % m
使用扩展欧拉定理需要满足
x
≥
φ
(
m
)
x \ge \varphi(m)
x≥φ(m) ,所以需要先算一部分
x的初值就是b
#include <bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
int minDiv[maxn],phi[maxn],sum[maxn];
int T,flag,i;
long long a,x,ep,t,m,res;
void genPhi()
{
for (int i=1;i<maxn;i++)
{
minDiv[i]=i;
}
for (int i=2;i*i<maxn;i++)
{
if (minDiv[i]==i)
{
for (int j=i*i;j<maxn;j+=i)
{
minDiv[j]=i;
}
}
}
phi[1]=1;
for (int i=2;i<maxn;i++)
{
phi[i]=phi[i/minDiv[i]];
if ((i/minDiv[i]) % minDiv[i]==0)
{
phi[i]*=minDiv[i];
}
else
{
phi[i]*=minDiv[i]-1;
}
}
}
long long q_p(long long a,long long x,long long MOD)
{
long long e = a; long long res = 1;
while (x)
{
if (x&1) res = (res * e) % MOD;
e = (e * e) % MOD;
x >>= 1;
}
return res;
}
long long dfs(long long x,long long t,long long m)
{
if (m == 1) return 0;
if (t == 1) return q_p(a,x,m);
ep = dfs(x,t-1,phi[m]);
ep = ep % phi[m] + phi[m];
return q_p(a,ep,m);
}
int main()
{
genPhi();
scanf("%d",&T);
while (T--)
{
scanf("%lld%lld%lld",&a,&t,&m);
//if (m == 1) {cout<<0<<endl; continue;}
x = 1; flag = 0; res = 1;
while (t--)
{
res = 1;
if (flag == 0) fo(i,1,x) {res = res * a; if (res > phi[m]) {flag = 1; break;}}
if (flag == 0) {x = res; continue;}
t++; break;
}
if (t > 0) res = dfs(x,t,m);
cout<<res%m<<endl;
}
return 0;
}