hdu5728PowMod+尤拉函式和+k的無窮次方取膜
阿新 • • 發佈:2019-02-03
Problem Description
Declare:
n is a square-free number.
φ is the Euler’s totient function.
find:
ans=
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;
}