题意:
给出c种颜色和s个珠子;
将珠子染色后穿成一个环;
旋转和翻转相同的视为同构;
求方案数;
题解:
polya计数的裸题;
定义m为颜色数,c(Pi)为Pi这个置换的循环节个数;
那么根据定理,答案L为;
然后只要求出各个置换的循环节就好了;
题中允许两种置换,先考虑旋转;
旋转有n种置换方式,分别是转0,转360/n,转2*360/n......转(n-1)*360/n;
每种的循环节数实际上是gcd,然后带入求和式;
然后考虑翻转,有奇偶的讨论;
奇数可以过每个珠子做对称轴,那么置换数就是n,循环节数都是n/2+1;
偶数可以过两个对角的珠子做对称轴,置换数是n/2,循环节数是n/2+1(其他的珠子除以2,加上轴上的两个);
也可以不过珠子,这样的置换数同样是n/2,循环节数是n/2了;
然后除个2*n就结束了;
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 110000
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
int t=a%b;
while(t)
{
a=b,b=t;
t=a%b;
}
return b;
}
int pow(int x,int y)
{
int ret=1;
while(y)
{
if(y&1)
ret*=x;
x*=x;
y>>=1;
}
return ret;
}
int main()
{
int n,m,i,j,k;
while(scanf("%d%d",&m,&n)&&(n||m))
{
for(i=1,k=0;i<=n;i++)
k+=pow(m,gcd(n,i));
if(n&1)
k+=n*pow(m,n/2+1);
else
k+=n/2*pow(m,n/2)+n/2*pow(m,n/2+1);
k/=2*n;
printf("%d\n",k);
}
return 0;
}