题目:http://poj.org/problem?id=2409
题意:用m种颜色给n个珠子染色,能染出多少种项链。如果旋转或翻转转后与之前的项链一模一样,那么这种染色方案不算。
分析:直接用polya定理解决。先考虑旋转置换,将项链顺时针旋转i个珠子,那么循环节数为gcd(n,i)。再考虑翻转置换,当n为奇数时,有n个循环节数为(n+1)/2的循环群,当n为偶数时,有n/2个循环节数为(n+2)/2的循环群和n/2个循环节数为n/2的循环群。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int my_pow(int a,int n)
{
int ans=1;
while(n)
{
if(n&1)
ans*=a;
n>>=1;
a*=a;
}
return ans;
}
int main()
{
int m,n,ans;
while(scanf("%d%d",&m,&n),(m+n))
{
ans=0;
for(int i=1;i<=n;i++)
ans+=my_pow(m,gcd(n,i));
if(n&1)
ans+=n*my_pow(m,(n+1)/2);
else
ans+=n/2*my_pow(m,n/2)+n/2*my_pow(m,(n+2)/2);
ans/=(2*n);
printf("%d\n",ans);
}
return 0;
}