您的位置:首页 > 大数据 > 人工智能

HDU5728 2016 Multi-University Training Contest 1 (递归+欧拉函数)

2016-07-23 13:44 483 查看
/*265秒跑出来的,调了一下午,时间再调不短了。。。
这个推公式就好,看看欧拉函数积性公式,再试着推几下就出来啦。*/
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=1e7+5;
ll sumphi[maxn];
int prime[maxn],phi[maxn];
bool vis[maxn];
int cnt,a[maxn],rear;
void init(){
sumphi[1]=phi[1]=1;
cnt=0;
for(int i=2;i<maxn;i++){
if(!vis[i]){phi[i]=i-1;prime[cnt++]=i;}
for(int j=0;j<cnt;j++){
if(i*prime[j]>=maxn)break;
vis[i*prime[j]]=true;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];break;
}else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
sumphi[i]=(sumphi[i-1]+phi[i])%mod;
}
}

void resolve(int n)
{
for(int i=0;i<cnt;i++)
{
if(!vis
) {a[rear++]=n;break;}
if(n%prime[i]==0)
{
if(n==0)
return;
a[rear++]=prime[i];
n/=prime[i];
}
}
}

ll solve(int n,int m,int res)
{
if(n==1)
return sumphi[m];
if(m==1)
return phi
;
if(m<1)
return 0;
return ((a[res]-1)*solve(n/a[res],m,res-1)%mod+solve(n,m/a[res],res)%mod)%mod;
}
ll pow(ll a,ll b,int p){
ll ret=1;
a%=p;
while(b)
{
if(b&1) ret=(ret*a)%p;
a=(a*a)%p;
b/=2;
}
return ret;
}
ll f(ll k,int p)
{
if(p==1) return 0;
ll tmp=f(k,phi[p]);
return pow(k,tmp+phi[p],p);
}
int main()
{
init();
ll p,n,m;
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
rear=0;
resolve(n);
ll k=solve(n,m,rear-1);
printf("%lld\n",f(k,p));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: