poj 2409 Let it Bead【polya定理+burnside引理】
两种置换
旋转:有n种,分别是旋转1个2个……n个,旋转i的循环节数位gcd(i,n)
翻转:分奇偶,对于奇数个,只有一个珠子对一条边的中点,循环节数为n/2+1;对于偶数个,有珠子对珠子和边对边,循环节个数为n/2+1个和n/2个
然后用polya定理即可
#include<iostream>
#include<cstdio>
using namespace std;
long long n,k,ans;
long long ksm(long long a,long long b)
{
long long r=1;
while(b)
{
if(b&1)
r=r*a;
a=a*a;
b>>=1;
}
return r;
}
long long gcd(long long a,long long b)
{
return !b?a:gcd(b,a%b);
}
int main()
{
while(scanf("%d%d",&k,&n)&&k+n)
{
ans=(n&1)?ksm(k,n/2+1)*n:ksm(k,n/2+1)*n/2+ksm(k,n/2)*n/2;
for(int i=1;i<=n;i++)
ans+=ksm(k,gcd(i,n));
printf("%lld\n",ans/2/n);
}
return 0;
}