数学:Burnside引理与Pólya定理

这个计数定理在考虑对称的计数中非常有用

先给出这个定理的描述,虽然看不太懂:

在一个置换群G={a1,a2,a3……ak}中,把每个置换都写成不相交循环的乘积。 

设C1(ak)是在置换ak的作用下不动点的个数,也就是长度为1的循环的个数。通过上述置换的变换操作后可以相等的元素属于同一个等价类 那么等价类的个数就等于:

然后理解一下公式

一正方形分成4格,2着色,有多少种方案?其中,经过转动相同的图象算同一方案。

关于转动,一共有四种置换方法,也就是|G|=4

不动(360度):a1=(1)(2)…(16)
逆时针转90度 :a2=(1)(2)(3 4 5 6)(7 8 9 10) (11 12)(13 14 15 16)
顺时针转90度 :a3=(1)(2)(6 5 4 3)(10 9 8 7)(11 12)(16 15 14 13)
转180度:a4=(1)(2)(3 5)(4 6)(7 9)(8 10)(11)(12) (13 15)(14 16)

然后我们针对每一种置换的方式,找到其中的不动点,也就是只有自己的情况

由Burnside引理,共有(16+2+2+4)/4=6(种方案)

然后的Pólya定理其实就是简化这个运算用的

利用Burnside引理要首先列出所有n^m种可能的染色方案,然后找出在每个置换下保持不变的方案数。

然后找出在每个置换下保持不变的方案数,显然当m或n很大的时候,复杂度会炸

Polya定理实际上是Burnside引理的具体化,提供了计算不动点的具体方法

假设一个置换有σk个循环,就是轮换

易知每个循环对应的所有位置颜色需一致,而任意两个循环之间选什么颜色互不影响。

因此,如果有m种可选颜色,则该置换对应的不动点个数为m^σk。

用其替换Burnside引理中的C(G),即C(G)=m^k。得到等价类数目为:

 

 老实说,我看不懂这个怎么用的。。

burnside定理就是 非等价染色数 = 在G中单个置换下保持不变的染色数的平均数

而polya定理说的是一种特殊情况,若有m中颜色,每种颜色不限数量,则在G中的某个置换g下,保持不变的染色数=m^k,k为置换g的循环个数

 典型例题POJ1286

我们需要求的也就是不同置换的个数,和每一个置换的循环节数

旋转,旋转i个小球的距离,那么会得到0~n-1的置换方案,共有n种,对于旋转i个小球的循环节数为gcd(n,i)

翻转,对于偶数,不经过小球有对称抽有n/2个,每种置换方案有n/2+1个循环节;经过小球的对称轴有n/2个,每种置换方案有n/2个循环节

对于奇数,经过小球的对称轴,有n个,每种方案有n/2+1个循环节

 1 #include<cstdio>
 2 long long n,ans;
 3 long long gcd(long long a,long long b)
 4 {
 5     return b==0?a:gcd(b,a%b);
 6 }
 7 long long pow(long long x,long long k)
 8 {
 9     if(k==1) return x;
10     long long s=pow(x,k/2);
11     s=s*s;
12     if(k%2) s*=x;
13     return s;
14 }
15 int main()
16 {
17     while(scanf("%lld",&n)==1&&n!=-1)
18     {
19         if(n==0)
20         {
21             printf("0
");
22             continue;
23         }
24         ans=0;
25         for(int i=0;i<n;i++)
26             ans+=pow(3,gcd(n,i));
27         if(n%2)
28         {
29             ans+=n*pow(3,n/2+1);
30         }
31         else
32         {
33             ans+=n/2*pow(3,n/2);
34             ans+=n/2*pow(3,n/2+1);
35         }
36         printf("%lld
",ans/(n*2));
37     }
38     return 0;
39 }
原文地址:https://www.cnblogs.com/aininot260/p/9568413.html