今天欧拉降幂,怎么操作姿势都不对。。。。。
例题:
The Preliminary Contest for ICPC Asia Nanjing 2019:
B super_log:
求 b 个 a ^ a ^ a ^ a ^ a ^ a ^ a :
很明显就是欧拉降幂:
然而就这破题。。卡了我20多发。
贴上代码。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<deque>
#include<map>
#include<vector>
#include<cmath>
#define ll long long
#define llu unsigned ll
using namespace std;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int maxn=1001000;
const int mod=1e9+7;
int p[maxn],prime[maxn];
bool ha[maxn];
int cnt=0;
void Prime(void)
{
p[1]=1;
ha[1]=true;
for(int i=2;i<maxn;i++)
{
if(!ha[i])
{
prime[cnt++]=i;
p[i]=i-1;
}
for(int j=0;j<cnt&&i*prime[j]<maxn;j++)
{
ha[i*prime[j]]=true;
if(i%prime[j]==0)
{
p[i*prime[j]]=p[i]*prime[j];
break;
}
p[i*prime[j]]=p[i]*p[prime[j]];
}
}
}
ll mypow(ll a,ll b,ll mod)
{
ll ans=1;
if(a>=mod) a=a%mod+mod;
while(b)
{
if(b&1)
{
ans=ans*a;
if(ans>=mod) ans=ans%mod+mod;
}
//a也要像ans一样判断,因为a对最终答案是有贡献的。
a=a*a;
if(a>=mod) a=a%mod+mod;
b>>=1;
}
return ans;
}
ll a,b,m;
ll dfs(ll pm,ll cnt)
{
if(cnt==0) return 1%pm;
if(a%pm==0) return pm;
return mypow(a,dfs(p[pm],cnt-1),pm);
}
int main(void)
{
Prime();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&a,&b,&m);
printf("%lld\n",dfs(m,b)%m);
}
return 0;
}