[POJ2409]Let it Bead - Polya定理

Posted daklqw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POJ2409]Let it Bead - Polya定理相关的知识,希望对你有一定的参考价值。

求长度为 \\(n\\) 的环染色方案数,旋转翻转同构。


直接从 Polya 定理开始。

考虑一下这个置换群长怎么样:

发现可以用二元组 \\((x,y) (x \\in [0,n),y \\in {0,1})\\) 来描述每一个元素,表示旋转度数和是否翻转。

先考虑 \\(y=0\\),这是经典结论,循环数为 \\(\\gcd(x,n)\\)

再考虑 \\(y=1\\)。考虑操作 \\(n-(x+p)\\bmod n\\),画画发现可能会两两配对。

考虑它的复合:\\(n-(n-(x+p)+p)=x\\),竟然真的配对了。

但是显然奇数一定有孤立的。

这个时候奇偶要分开讨论。

我们考虑方程 \\(n-x-p \\equiv x \\pmod n\\) 的解。

显然模数是奇数的时候有逆元,所以有唯一一个孤立点,循环数为 \\(\\frac{n+1}{2}\\)

当模数是偶数时,如果 \\(n-p\\) 是奇数,方程无解,有 \\(\\frac{n}{2}\\) 个循环。

否则根据值域得出所有可行的 \\(x\\),当 \\(p \\leq \\frac{n}{2}\\),则 \\(x=\\frac{n+p}{2}\\)\\(\\frac{2n+p}{2}\\),否则是 \\(\\frac{2n+p}{2}\\)\\(\\frac{3n+p}{2}\\)

此时循环数为 \\(\\frac{n+2}{2}\\)

用 Polya 公式,即颜色循环数次方求和除以群大小,即可。

#include <iostream>
#include <cstdio>
using namespace std;
#define LLI long long
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
int fastpow(int a,int b){int res=1;
for(;b;b>>=1,a=a*a)if(b&1)res=a*res;return res;}
int main(){
	int a,b;LLI ans;
	while(scanf("%d%d",&a,&b)==2){
		if(a==0&&b==0)break;
		ans=0;
		for(int i=1;i<=b;++i)ans+=fastpow(a,gcd(i,b));
		if(b&1)ans+=1LL*b*fastpow(a,b+1>>1);
		else ans+=1LL*(a+1)*(b>>1)*fastpow(a,b>>1);
		ans/=b<<1;
		printf("%lld\\n",ans);
	}
	return 0;
}

以上是关于[POJ2409]Let it Bead - Polya定理的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2409 Let it Bead(置换burnside引理)

POJ 2409-Let it Bead(Polya计数)

[ACM] POJ 2409 Let it Bead (Polya计数)

POJ2409 Let it Bead

POJ2409Let it Bead Pólya定理

POJ 2409 Let it Bead [置换群 Polya]