题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5728
【题意】欧拉函数求和得到k,再求k^k^k.....^k(无限个)%p。
【分析】ORZ没有公式一切都是妄谈。。贴上公式:∑i=1mφ(i∗n)=φ(p)∗∑i=1mφ(i∗pn)+∑i=1m/pφ(i∗n).
ab%p=aφ(p)+b%φ(p)%p 递归实现公式即可。
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
#define LL long long
#define MAXN 10000001
const int mod=1e9+7;
bool isprime[MAXN];
int prime[MAXN];
int Euler[MAXN];
int a[20];
LL sum[MAXN];
int cnt;
LL cal(LL p,LL n,LL m){
if(n==1)
return sum[m];
if(m==0)
return 0;
return ((a[p]-1)*cal(p-1,n/a[p],m)%mod+cal(p,n,m/a[p]))%mod;
}
LL Pow(LL k,LL p){
if(p==1)
return 0;
int Ep=Euler[p];
LL b=Ep+Pow(k,Ep);
LL ret=1;
while(b){
if(b&1)
ret=(ret*k)%p;
b>>=1;
k=(k*k)%p;
}
return (ret+p)%p;
}
int main(){
Euler[1]=1;
cnt=0;
memset(isprime,0,sizeof(isprime));
isprime[0]=isprime[1]=1;
for(int i=2;i<MAXN;++i){
if(!isprime[i]){
prime[cnt++]=i;
Euler[i]=i-1;
}
for(int j=0;j<cnt && i*prime[j]<MAXN;++j){
isprime[i*prime[j]]=1;
if(i%prime[j]==0){
Euler[i*prime[j]]=Euler[i]*prime[j];
break;
}
else
Euler[i*prime[j]]=Euler[i]*(prime[j]-1);
}
}
sum[0]=0;
for(int i=1;i<MAXN;++i)
sum[i]=(Euler[i]+sum[i-1])%mod;
int n,m,p;
while(cin>>n>>m>>p){
int now=n,tmp=0;
for(int i=0;i<cnt;++i){
if(!isprime[now]){
a[tmp++]=now;
break;
}
if(now%prime[i]==0){
a[tmp++]=prime[i];
now/=prime[i];
}
}
LL k=cal(tmp-1,n,m);
LL ans=Pow(k,p);
cout<<ans<<endl;
}
}