//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/8/3.
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b)
{
return b==0?a:gcd(b,a%b);
}
LL polya(LL m,LL n)
{
LL result=0;
for(int i=1;i<=n;i++)
result+=pow(m,gcd(n,i));
if(n%2)
result+=pow(m,(n+1)/2)*n;
else
result+=(pow(m,n/2)+pow(m,n/2+1))*n/2;
return result/n/2;
}
int main()
{
LL m,n;
while(scanf("%lld%lld",&m,&n)&&m+n)
printf("%lld\n",polya(m,n));
return 0;
}
用欧拉函数优化过后的代码
#include<iostream>
#include<cmath>
using namespace std;
typedef long long LL;
LL euler(LL n)
{
LL ans=n;
for(LL i=2;i*i<=n;i++)
{
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
LL polya(LL m,LL n)
{
LL result=0;
for(LL i=1;i*i<=n;i++)
{
if(n%i!=0) continue;
result+=euler(i)*pow(m,n/i);
if(i*i==n) break;
result+=euler(n/i)*pow(m,i);
}
if(n%2)
result+=pow(m,(n+1)/2)*n;
else
result+=(pow(m,n/2)+pow(m,n/2+1))*n/2;
return result/n/2;
}
int main()
{
LL m,n;
while(cin>>m>>n)
{
if(m+n==0) break;
cout<<polya(m,n)<<endl;
}
return 0;
}