#include<cstdio>
#include<iostream>
using namespace std;
const int MOD = 1000000007;
typedef long long LL;
LL n, m;
int prime[37000],is[37000];
void getprime(){
int cnt=0;
for(int i=2;i<37000;i++){
if(!is[i]){
prime[cnt++]=i;
for(int j=i;j<37000;j+=i)
is[j]=1;
}
}
}
LL pow(LL x,LL n)
{
LL t=1;
while(n){
if(n&1)t=(t*x)%MOD;
x=(x*x)%MOD;
n >>= 1;
}
return t%MOD;
}
LL getptr(LL p,LL i)
{
LL tmp=pow(p-1,i);
if(i&1)
tmp=(tmp+MOD-(p-1))%MOD;
else
tmp=(tmp+p-1)%MOD;
return tmp;
}
LL eular(LL x)
{
if(x==1)return 1;
LL rep=x;
for(int i=0;prime[i]*prime[i]<=x;i++){
if(x%prime[i]==0){
rep-=rep/prime[i];
x/=prime[i];
}
while(x%prime[i]==0)
x/=prime[i];
if(x==1)break;
}
if(x!=1)rep-=rep/x;
return rep%MOD;
}
LL inv(LL n)
{
return pow(n,MOD-2)%MOD;
}
int main(){
getprime();
while(cin>>n>>m){
LL ans=0;
int i;
m--;
for(i = 1;i * i < n;i++){
if(n%i==0){
ans=(ans+(getptr(m,i)*eular(n/i))%MOD)%MOD;
ans=(ans+(getptr(m,n/i)*eular(i))%MOD)%MOD;
}
}
if(i*i==n)
ans=(ans+(getptr(m,i)*eular(n/i))%MOD)%MOD;
ans=((m+1)*ans)%MOD;
ans=(ans*inv(n))%MOD;
cout<<ans<<endl;
}
}
hdu 2865 基础polya问题
最新推荐文章于 2019-01-08 08:27:55 发布