【群论相关】Burnside引理&Polya定理

文章目录

        • 置换
        • 不动点&等价类
        • Burnside引理
        • Polya定理
        • 例题
          • [poj2154-Color](http://poj.org/problem?id=2154)
          • [bzoj1478: Sgu282 Isomorphism](https://www.lydsy.com/JudgeOnline/problem.php?id=1478)
        • 引用


由一个集合 G G G和一个运算 ⋅ · 构成,运算过程即为集合中任何两个元素 a , b a,b a,b a ⋅ b a·b ab的过程,运算 ⋅ · 为具体给出的任意一种可行的运算,需要满足群公理的四个要求:

  1. 封闭性: ∀ a , b ∈ G , ∃ c ∈ G , a ⋅ b = c \forall a,b\in G,\exists c\in G,a·b=c a,bG,cG,ab=c
  2. 结合律: ∀ a , b , c ∈ G , ( a ⋅ b ) ⋅ c = a ⋅ ( b ⋅ c ) \forall a,b,c\in G,(a·b)·c=a·(b·c) a,b,cG,(ab)c=a(bc)
  3. 单位元: ∃ e ∈ G , ∀ a ∈ G , a ⋅ e = e ⋅ a = a \exists e\in G,\forall a\in G,a·e=e·a=a eG,aG,ae=ea=a
  4. 逆元: ∀ a ∈ G , ∃ b ∈ G , a ⋅ b = b ⋅ a = e , 记 b = a − 1 \forall a\in G,\exists b\in G,a·b=b·a=e,记b=a^{-1} aG,bG,ab=ba=eb=a1

置换

下面是一个置换,

( 1 2 3 . . . n a 1 a 2 a 3 . . . a n ) \begin {pmatrix} 1 & 2 & 3 & ... & n \\ a_1 & a_2 & a_3 & ... & a_n \end {pmatrix} (1a12a23a3......nan)

将群的运算(即基本变换方式)用 f : a i ( 1 ≤ i ≤ n ) ( n 为 G 中 元 素 个 数 , a i 互 不 相 同 , a i ∈ { 1 , 2 , . . . , n } ) f:a_i(1\leq i\leq n)(n为G中元素个数,a_i互不相同,a_i\in \{ 1,2,...,n\}) f:ai(1in)(nG,ai,ai{1,2,...,n})表示。具体置换为把初状态 ( 1 , 2 , 3 , . . . , n ) (1,2,3,...,n) (1,2,3,...,n)的任意排列,用 a i a_i ai替代 i i i(设序列第 x x x个位置上的元素为 i i i,替代后序列上第 x x x个位置上的元素为 a i a_i ai)而得到新的一种排列,以上变换即为置换。

同样也可以看做置换 f : a i f:a_i f:ai分解成若干个不相关的循环组,每个循环组内的元素构成一个环,每个环上的元素都可以移动到下一个环上的位置而回到初始状态( i − > a i , a i − > a a i , . . . , − > i i->a_i,a_i->a_{a_i},...,->i i>ai,ai>aai,...,>i),也就是集合的一一映射关系。群则将置换的过程中元素的位置变换转化成了运算,用数学符号表示出来。

将置换看做群的运算方式,一个封闭群即为一个置换群。


不动点&等价类

设存在一种群内元素的排列方式 q i q_i qi,使得经过置换 f : a i f:a_i f:ai后的排列与原来相同( i = a i = a a i = . . . = i i=a_i=a_{a_i}=...=i i=ai=aai=...=i)。则 q i q_i qi这种排列方式的状态是 f : a i f:a_i f:ai置换的不动点。

等价类即是定义一种等价关系,一个状态若可以通过特定的置换得到另一个状态,则这两个状态是等价的,同属一个等价类。

一些题目中“求本质不同的方案”,就是求等价类个数。


Burnside引理

设置换 g : a i g:a_i g:ai的在可行的染色方案中的不动点个数为 C ( g ) C(g) C(g) G G G ∣ G ∣ |G| G个不同的置换群的集合,则等价类个数为:

1 ∣ G ∣ ∑ i = 1 ∣ G ∣ C ( g i ) \frac 1 {|G|}\sum _{i=1} ^{|G|}C(g_i) G1i=1GC(gi)

举个例子:

假设给正方形棋盘染黑白两色,轴对称同构,求本质不同方案数。

那么需要考虑:

  1. 水平对称 2.纵向对称 3.左上->右下斜对角线对称 4.右上->左下斜对角线对称

这四种置换,也就是四个置换群,分别求不动点个数即可。


Polya定理

B u r n s i d e Burnside Burnside引理需要枚举所有置换的情况来求不动点,复杂度太高,于是引入 P o l y a Polya Polya定理来更简捷地求置换群的不动点个数。

之前提到了可以将置换 f : a i f:a_i f:ai分解成若干个循环组,考虑对于不动点来说,每个循环组中的元素的状态(颜色)必须完全一致,而不同循环组之间互不相关。因此对于置换 f : a i f:a_i f:ai,有 x x x种可选的颜色,循环组个数为 k k k C ( f ) = x k C(f)=x^{k} C(f)=xk,更新 B u r n s i d e Burnside Burnside引理的式子,得到等价类个数为:

1 ∣ G ∣ ∑ i = 1 ∣ G ∣ x i k i \frac 1{|G|}\sum_{i=1} ^{|G|}x_i^{k_i} G1i=1Gxiki

还是上面的例子,这时只需要观察求出不动点个数即可,一般来说题目中所求的不动点都有一些特殊的规律和性质,以保证快速求出。


例题

poj2154-Color

N N N种颜色染一条长度为 N N N的项链,旋转同构,求本质不同方案数。

观察规律发现对于旋转 1 , . . . , n 1,...,n 1,...,n次的不同置换而言,循环组个数即为 g c d ( n , i ) gcd(n,i) gcd(n,i)

再套用 B u r n s i d e Burnside Burnside引理, P o l y a Polya Polya定理,等价类个数为:

∑ 1 n n g c d ( n , i ) \sum_1^nn^{gcd(n,i)} 1nngcd(n,i)

= ∑ d ∣ n n d ∑ i = 1 n d [ g c d ( i , n d ) = 1 ] =\sum_{d|n} n^d \sum_{i=1} ^{\frac n d}[gcd(i,\frac n d)=1] =dnndi=1dn[gcd(i,dn)=1]

= ∑ d ∣ n n d ϕ n d =\sum _{d|n} n^d \phi \frac n d =dnndϕdn

这样就可以 O ( n × log ⁡ n ) O(\sqrt n\times \log n) O(n ×logn)计算了,没有考虑求 ϕ d \phi d ϕd的复杂度,似乎远小于 d \sqrt d d

代码

#include
#include
#include
using namespace std;
const int N=4e4,MX=1e9;
typedef long long ll;
int T,n,mod,ans,p[N],tot;
bool pri[N];
map<int,int>phi;
inline int mul(int x,int y){return x*y%mod;}
inline int ad(int x,int y){x+=y;if(x>=mod) x-=mod;return x;}

inline void pre()
{
	int i,j;ll res;
	for(i=2;i<=MX/i;++i){
		if(!pri[i]) p[++tot]=i;
	    for(j=1;j<=tot;++j){
	    	res=i*p[j];if(res*res>MX) break;
			pri[res]=true;
	    	if(i%p[j]==0) break;
	    }
	}
}

inline int fp(int x,int y)
{
	int re=1;x%=mod;
	for(;y;y>>=1,x=mul(x,x))
	 if(y&1) re=mul(re,x);
	return re;
}

inline int PHI(int x)
{
	if(x==1) return 1;
	int i,re=x;
	for(i=1;i<=tot && p[i]*p[i]<=x;++i)
	  if(x%p[i]==0){
	  	for(;x%p[i]==0;x/=p[i]);
		re=re/p[i]*(p[i]-1);
	  }
	if(x!=1) re=re/x*(x-1);
	return re%mod;
}

int main(){
	int i;
	pre();
	scanf("%d",&T);
	for(;T;--T){
		ans=0;
		scanf("%d%d",&n,&mod);
	    for(i=1;i<=n/i;++i) if(n%i==0){
			ans=ad(ans,mul(fp(n,i-1),PHI(n/i)));
	    	if(i*i!=n) 
			  ans=ad(ans,mul(fp(n,n/i-1),PHI(i)));
	    }
	    printf("%d\n",ans);
	}
}

m a p map map W A WA WA p o j poj poj # i n c l u d e < b i t s / s t d c + + . h > \# include<bits/stdc++.h> #include<bits/stdc++.h> C E CE CE,每次做 p o j poj poj都会先 C E CE CE多次…

bzoj1478: Sgu282 Isomorphism

题解
算是一个非常巧妙的运用了。


引用

  • 知乎:如何直观地理解群论?
  • Burnside引理与Polya定理-byQAQqwe
  • 初涉OI中的群论(Burnside引理和Polya定理)-bylitble

以上写的都非常清晰易懂,总之比我写的好多啦。

你可能感兴趣的:(【群论相关】Burnside引理&Polya定理)