1. 程式人生 > >hdu5728PowMod+尤拉函式和+k的無窮次方取膜

hdu5728PowMod+尤拉函式和+k的無窮次方取膜

Problem Description
Declare:
k=mi=1φ(in)mod1000000007

n is a square-free number.

φ is the Euler’s totient function.

find:
ans=kkkk...k mod p

There are infinite number of k

Input
Multiple test cases(test cases ≤100), one line per case.

Each line contains three integers, n,m and p.

1≤n,m,p≤107

Output
For each case, output a single line with one integer, ans.

Sample Input

1 2 6
1 100 9

Sample Output

4
7

Author
HIT

Source
2016 Multi-University Training Contest 1

這裡寫圖片描述

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
using namespace std
; #define LL long long const int mod=1000000007; const int maxn=10000005; bool check[maxn]; //用於打表記錄的中間量 LL sumPhi[maxn]; //前i個的尤拉函式和 int cnt,phi[maxn],prime[maxn]; //素數個數,尤拉表,素數表 //素數表是第幾個素數是什麼,尤拉表是i的尤拉是phi[i]; void init(){ //素數+尤拉表 phi[1]=1; cnt=0; for(int i=2;i<maxn;i++){ if
(!check[i]){ phi[i]=i-1; prime[cnt++]=i; } for(int j=0;j<cnt;j++){ if(i*prime[j]>=maxn)break; check[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[0]=0; for(int i=1;i<maxn;i++) sumPhi[i]=(sumPhi[i-1]+phi[i])%mod; } LL phiz(int n,int m){ //計算k, if(n==1) return sumPhi[m]; if(m==1) return phi[n]; if(m<1) return 0; for(int i=0;i<cnt;i++){ if(n%prime[i]==0){ //n的最小質數prime[i] LL temp1=(prime[i]-1)*phiz(n/prime[i],m)%mod; LL temp2=phiz(n,m/prime[i])%mod; return (temp1+temp2)%mod; } } return 0; } 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 powe(LL k,int p){ //k^b%p if(p==1) return 0; LL temp=powe(k,phi[p]); return pow(k,temp+phi[p],p); } int main(){ init(); int n,m,p; while(scanf("%d %d %d",&n,&m,&p)!=EOF){ LL k=phiz(n,m); printf("%I64d\n",powe(k,p)); } return 0; }