题意:
给出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; }
原文地址:http://blog.csdn.net/ww140142/article/details/47003643