1. 程式人生 > >等價類計數:Burnside引理 & Polya定理

等價類計數:Burnside引理 & Polya定理

提示: 本文並非嚴謹的數學分析,有很多地方是自己瞎口胡的,僅供參考。有錯誤請不吝指出 :p ## 1. 群 ### 1.1 群的概念 群 $(S,\circ)$ 是一個元素集合 $S$ 和一種二元運算 $ \circ $ 的合稱,其滿足以下性質。 ##### 封閉性 >對於 $\forall a,b \in S$ , $\exist c \in S$ 使得 $c = a \circ b$ ##### 結合律 >對於 $\forall a,b,c \in S$ , $a \circ (b \circ c) = (a \circ b) \circ c$ ##### 單位元 >$\exist I \in S$ ,使得對於 $\forall a \in S$ , $a \circ I = I \circ a = a$ 根據定義,單位元具有唯一性,即一個群只有一個單位元。 證明:設 $a,b$ 都是 $S$ 的單位元,則 $a = a \circ b = b$ ,兩者實質上相同。 ##### 逆元 >對於 $\forall a \in S$ , $\exist a^{-1} \in S$ ,使得 $a \circ a^{-1} = a^{-1} \circ a = I$ 根據定義,逆元具有唯一性,即每個元素有且僅有一個逆元。 證明:設 $a$ 有兩個逆元 $b,c$ ,則 $b = b \circ I = b \circ (a \circ c) = (b \circ a) \circ c = I \circ c = c$ ,兩者實質相同。 這也同時說明了不存在兩個元素 $a, b$ 的逆元是同一個元素 $c$,因為 $c$ 只有唯一一個逆元。 即逆元是一一對應的。 ### 1.2 更抽象的群 我們更進一步,將 $S$ 中的每一個元素視為一個函式, 預設 $\circ$ 代表函式的複合,即 $(f \circ g) (x) = f(g(x))$。所以現在一個群可以只用一個函式集合 $S$ 來表示。 例如,記 $r_\theta (x)$ 表示將 $x$ 旋轉 $\theta$ 度,那麼 $S = \{ r_{0^\circ}, r_{90^\circ},r_{180^\circ},r_{270^\circ}\}$ 就是一個群。 證明一下,顯然有封閉性和結合律。 單位元是 $r_{0^\circ}$ ,因為 $r_{0^\circ} (r_\theta(x)) = r_{\theta^\circ} (r_0 (x)) = r_\theta(x)$ $S$ 中元素 $r_\theta $ 的逆元便是 $r_{360^\circ - \theta}$ ,因為他們兩個捲起來就是 $I = r_{0^{\circ}}$ ### 1.3 提示 由於群滿足封閉性,所以我們在尋找群的時候一定要“找完”所有可能的狀態,例如 $\{ r_{0^\circ}, r_{90^\circ}\}$ 就不是一個群。 ## 2. Burnside 首先明確這個定理是用來幹什麼的——等價類計數。 注:通常我使用 $a,b,c,d \in C$ 表示計數物件, $f,g,h \in G$ 表示變換。 ### 2.1 等價 >給定一個作用在計數集合 $C$ 上的變換集合 $G$,若 $C$ 中計數物件 $d$ 可以由計數物件 $c$ 通過 $G$ 中變換得到,即 $\exist f \in G$ 使得 $d = c \circ f$,我們便稱 $c$ 與 $d$ 等價,記作 $c \sim d$ 。 $G$ 其實就是個函式集合,其中的函式都接受 $C$ 中元素作為引數,輸出也是 $C$ 中元素。 類似的我們記 $f(c)$ 為 $c \circ f$ ,表示對計數物件 $c$ 做變換 $f$ 。 我們同樣可以對一個函式做變換,即 $f \circ g$ 是允許的。請參考上文“1.2 更抽象的群”。 在Burnside中,**我們要求 $G$ 是一個群**。這樣我們可以匯出一些關於等價的性質。 ##### 自反性 >$a \sim a$ 因為 $G$ 是群,故有單位元 $I \in G$ , $a \circ I = a$ ,滿足等價定義。 ##### 對稱性 >$a \sim b \iff b \sim a$ 設 $a \circ f = b$ ,因為 $G$ 是群,故存在 $f^{-1}$ 使得 $b \circ f^{-1} = a$ ,滿足等價定義。同理反向再證一次即可得出充分完全性。 ##### 傳遞性 >$a \sim b , b \sim c \Rightarrow a \sim c$ 設 $a \circ f = b, b \circ g = c$,因為 $G$ 是群,所以 $f \circ g \in G$(封閉性),$a \circ (f \circ g) = (a \circ f) \circ g = b \circ g = c$,滿足等價定義。 ### 2.2 等價類及等價類計數 等價類即所有等價的計數元素的集合。計數集合 $C$ 由許多個等價類構成,好比連通塊。 統計 $C$ 中有多少個等價類,就是等價類計數。 如何快速的等價類計數,便是我們接下來所研究的。 ### 2.3 弱化版 不妨先來研究一個弱化版本,這可以幫助我們捋清思路。 #### 2.3.1 引理 >若對於 $\forall c \in C,f \in G \quad (f \not= I)$ , $c \circ f \not= c$ 都成立,那麼對於 $\forall c \in C, f \in G,g \in G \quad (f \not= g)$ ,都有 $c \circ f \not= c \circ g$ ,即與 $\forall c$ 等價的元素有且僅有 $|G|$ 個。 利用反證法。若 $\exist c,f,g$ 使得 $c \circ f = c \circ g$ ,那麼有 $c \circ f \circ g^{-1} = c$ ,即 $c \circ (f \circ g^{-1}) = c$ 。同時因為 $f \not= g$ ,所以 $f \circ g^{-1} \not= I$ 。於是與假設產生矛盾,故引理成立。 對 $c$ 做變換得到的元素兩兩不同,共有 $|G|$ 種變換,故有且僅有 $|G|$ 個元素與 $c$ 等價。 #### 2.3.2 弱化版Burnside >若對於 $\forall c \in C,f \in G \quad (f \not= I)$ , $c \circ f \not= c$ 都成立,那麼 >$$ >等價類計數 = \frac{|C|}{|G|} >$$ 這是肉眼可得的結論。由引理,對於 $\forall c$ ,都有且僅有 $|G|$ 個互不相同的元素與其等價。由於等價的傳遞性,這 $|G|$ 個元素是封閉的,實質上形成了許多個大小為 $|G|$ 的等價類。那麼等價類個數自然就是總計數元素個數 $|C|$ 除以每個等價類的大小 $|G|$ 了。 ### 2.4 標準版 弱化版的關鍵之處在於引理, $c \circ f \not= c$ 讓我們知道每個 $c$ 有 $|G|$ 個互不相同的元素與其等價。我們將這個條件和這個引理做一些“推廣”。 #### 2.4.1 穩定核 & 不動點 >穩定核 $G(c)$ :對於計數物件 $c$ ,使得 $c \circ f = c$ 的所有變換 $f$ 的集合,即 $\{ f \in G | c \circ f = c \}$ > >不動點 $C(f)$ :對於變換 $f$ ,使得 $c \circ f = c$ 的所有計數物件 $c$ 的集合,即 $\{ c \in C | c \circ f = c \}$ 注意單個字母 $G$ 代表整個變換集合;而 $G(c)$ 是根據計數元素 $c$ 生成的一個被 $G$ 包含的變換集合; 注意單個字母 $C$ 代表整個計數集合;而 $C(f)$ 是根據變換 $f$ 生成的一個被 $C$ 包含的計數集合。 #### 2.4.2 引理1 >$$ >\sum_{c \in C} |G(c)| = \sum_{f \in G} |C(f)| >$$ 證明: $$ \begin{aligned} \sum_{c \in C} |G(c)| &= \sum_{c \in C} \sum_{f \in G} [c \circ f = c] \\ &= \sum_{f \in G} \sum_{c \in C} [c \circ f = c] \\ &= \sum_{f \in G} |C(f)| \end{aligned} $$ 其實質是更換列舉方式。 #### 2.4.3 引理2 >對於 $\forall c$ , $G(c)$ 是個群。 分別證明群的四個性質即可。 ##### 封閉性 對於 $\forall f,g \in G(c)$ , $c \circ (f \circ g) = (c \circ f) \circ g = c \circ g = c$ ,所以 $f \circ g \in G(c)$ 。封閉性得證。 ##### 結合律 $G(c) \subseteq G$ ,結合律直接由 $G$ 給出。 ##### 單位元 $c \circ I = c$ ,所以 $I \in G(c)$ 。(這裡的 $I$ 代指 $G$ 的單位元) ##### 逆元 對於 $\forall f \in G(c)$ , $ c \circ f^{-1} = (c \circ f) \circ f^{-1} = c \circ (f \circ f^{-1}) = c$ ,所以 $f^{-1} \in G(c)$ 。 #### 2.4.4 引理3 >對於 $\forall c$ ,記 $S(c)$ 為與 $c$ 等價的計數元素的集合,有 >$$ >|S(c)| = \frac{|G|}{|G(c)|} >$$ 這個引理與弱化版引理2.3.1是對應關係。請對比起來理解。 我們的證明思路是:對於某個計數元素 $c$ ,求出 對於某個確定的變換 $f$ ,有多少個變換 $g$ 與其作用效果相同,即 $c \circ f = c \circ g$ 。 $$ c \circ f = c \circ g \iff c \circ f \circ g^{-1} = c \iff (f \circ g^{-1}) \in G(c) $$ 即 $f ,g$ 對 $c$ 的作用效果相同 等價於 $f \circ g^{-1}$ 在 $c$ 的穩定核內。 於是對於一個變換 $h \in G(c)$ ,根據群的基本性質,存在唯一的 $g^{-1} = f^{-1} \circ h$ ,使得 $f \circ g^{-1} = h$ 。變換 $h \in G(c)$ ,所以有 $|G(c)|$ 種取值; $f$ 是確定的,根據逆元唯一性, $f^{-1}$ 也是確定的;故 $g^{-1}$ 有 $|G(c)|$ 種取值。又由於逆元的一一對應性, $g$ 有 $|G(c)|$ 種取值。 即對於 $\forall f$ ,都有且僅有 $|G(c)|$ 個 $g$ 與其作用效果相同。 這說明了什麼?“作用效果相同”也是一種類似等價的關係,容易證明其具有傳遞性,於是他們是封閉的。作用效果相同的變換實質上形成 $\frac{|G|}{|G(c)|}$ 個大小為 $|G(c)|$ 的兩兩相連的連通塊或者說“作用效果相同等價類”,合起來構成了整個 $G$ 。我們便知道了 $c$ 通過變換可以變出 $\frac{|G|}{|G(c)|}$ 個不同的計數元素,即與 $c$ 等價的元素有 $\frac{|G|}{|G(c)|}$ 個,引理3證畢。 #### 2.4.5 Burnside >$$ >等價類計數 = \frac{1}{|G|}\sum_{f \in G} |C(f)| >$$ $$ \begin{aligned} \frac{1}{|G|}\sum_{f \in G} |C(f)| &= \frac{1}{|G|}\sum_{c \in C} |G(c)| \quad &\text{...引理1} \\ &= \frac{1}{|G|}\sum_{c \in C} \frac{|G|}{|S(c)|} \quad &\text{...引理3} \\ &= \sum_{c \in C} \frac{1}{S(c)} \\ &= 等價類計數 \end{aligned} $$ 倒數第二個式子,每個元素貢獻 $\frac{1}{S(c)}$ ,合起來便是等價類計數。這便是等價類計數的本質。 ### 2.5 Burnside的本質 ![來自zkx學長的課件《Polya計數.pptx》](https://img2020.cnblogs.com/blog/1437295/202003/1437295-20200321214711964-1926308585.jpg) >直接除以4不行,因為前四種找不到4個等價的情況 > >所以強行把它們補成4個就行了。。。 > >Burnside就是“強行補”的過程 > >——zkx Burnside的精髓就在於此。 Burnside弱化版,實際上是省掉了強行補的部分,使所有有效部分都在 $C(I)$ 。 >可以發現“群”是Burnside的唯一約束 > >這個約束幾乎就是沒有約束。。。 > >所以Burnside是非常通用的等價類計數法 > >——zkx ## 3. 置換群 (Burnside的內容已經結束,這裡開始是Polya了) ### 3.1 置換 一個置換長這樣: $$ (\begin{aligned} 1&,2,3,...,n \\ a_1&,a_2,a_3,...,a_n \end{aligned}) $$ 其中 $a_1,a_2,a_3,...,a_n$ 是一個 $n$ 排列。置換是一個接受序列,輸出序列的函式,它表示對每一個 $i$ ,將原序列第 $i$ 個數放到第 $a_i$ 個位置上。 ### 3.2 移位置換 一個普通的移位置換長這樣: $$ \tau_n = (\begin{aligned} 1,2,3,...,n&-1,n \\ 2,3,4,...,&n,1 \end{aligned}) $$ 即全員右移1位。很自然的可以拓展到 $k$ 位移位置換: $$ \tau_n^k = (\begin{aligned} 1,2,3,...&,n-1,n \\ k,k+1,...,n&,1,...,k-1 \end{aligned}) $$ 容易發現 $\tau_n^k$ 是 $k$ 個 $\tau_n$ 的複合,所以我們寫成乘方的形式。 ### 3.3 移位置換圖 移位置換 $\tau_n^k$ 所形成的圖:考慮將 $n$ 個點排成一個圓圈, $1$ 連 $k$ , $2$ 連 $k+1$ ,...,$n$ 連 $k-1$ 。 ![$tau_6^2$移位置換圖](https://img2020.cnblogs.com/blog/1437295/202003/1437295-20200321214746101-1332316242.png) 如圖便是 $\tau_6^2$ 形成的移位置換圖,共有兩個環。 ### 3.4 移位置換環個數定理 >$\tau_n^k$ 移位置換圖中環的個數為 $\gcd(k,n)$ 。 證明的思路同樣是已經使用多次的:求出對於一個數 $a$ ,有多少個數 $b$ 與它在同一個環內。 對於 $\forall a,b$ , $a,b$ 在同一個環內的條件為 $$ \begin{aligned} a \equiv b + ik \pmod n &\iff \exist i,j \quad s.t. \quad a = b + ik + jn \\ &\iff \exist i,j \quad s.t. \quad ik + jn = a - b \\ &\iff \gcd(k,n) | (a-b) \quad \text{...裴蜀定理} \end{aligned} $$ 最後兩個式子之間的轉化運用了二元整數解不定方程的有解條件,即裴蜀定理。 那麼這樣一來,對於 $\forall a$ ,顯然有且僅有 $\frac{n}{\gcd(k,n)}$ 個數與它在同一環內,故共有 $\gcd(k,n)$ 個環。(“在同一環內”傳遞性匯出的封閉性,這個方法在上文已經多次使用到) ## 4. Polya ### 4.1 概念 Polya是等價類計數的一個特殊版本,它的變換群 $G$ 是一個移位置換群,即 $$ G = \{ \tau_n^k \ | \ k \in [0,n), k \in Z \} $$ 顯然移位置換群是一個群 ~~廢話~~,證明很簡單,同樣是證明群的四個性質,這裡不再贅述。 用人話來說,Polya求解的一類問題計數基於一個環,而通過旋轉環能夠變得相同的方案算作一種(等價)。 比如經典的模板題: [洛谷P4980 Polya定理](https://www.luogu.com.cn/problem/P4980) >給定一個 $n$ 個點, $n$ 條邊的環,有 $m$ 種顏色,給每個頂點染色,問有多少種本質不同的染色方案,答案對 $10^9+7$ 取模。 > >本質不同定義為:只需要不能通過旋轉與別的染色方案相同。 ### 4.2 推導 有了前面那麼多的鋪墊,大名鼎鼎的Polya定理現在已經可以自己動手推出來了! 先寫出Burnside引理,並套入移位置換 $$ \begin{aligned} 等價類計數 &= \frac{1}{|G|}\sum_{f \in G} |C(f)| \\ &= \frac{1}{n}\sum_{i=1}^n |C(\tau_n^i)| \end{aligned} $$ 注: $\tau_n^n = \tau_n^0$ ,上面從 $1$ 到 $n$ 的列舉是對的 $|C(\tau_n^i)|$ 是什麼? $\tau_n^i$ 的不動點的個數,即要求 $\tau_n^i$ 移位置換圖裡同一環上點顏色相同的方案數。(為了做置換後看上去和原來一樣) 根據移位置換環個數定理, $\tau_n^i$ 有 $\gcd(n,i)$ 個環。有 $m$ 種顏色給 $\gcd(n,i)$ 個環去染,顯然方案數為 $m^{\gcd(n,i)}$ 。我們不侷限於本題推而廣之,方案數是一個關於環個數 $\gcd(n,i)$ 的函式 $f(\gcd(n,i))$ 。(也可以是關於環大小 $\frac{n}{\gcd(n,i)}$ 的函式,反正最重要的引數是 $\gcd(n,i)$ ) 帶入原式 $$ \frac{1}{n}\sum_{i=1}^n f(\gcd(n,i)) $$ 誒!這個式子裡面有 $\gcd$ ! 不用抑制住衝動,我們按照常見的莫反題目套路來。 $$ \begin{aligned} 等價類計數 &= \frac{1}{n}\sum_{i=1}^n f(\gcd(n,i)) \\ &= \frac{1}{n} \sum_{d|n} f(d) \sum_{i=1}^n [\gcd(n,i)=d] \quad &\text{...把gcd提出來列舉} \\ &= \frac{1}{n} \sum_{d|n} f(d) \sum_{i=1}^{\frac{n}{d}} [\gcd(\frac{n}{d},i)=1] \\ &= \frac{1}{n} \sum_{d|n} f(d) \varphi(\frac{n}{d}) \quad &\text{...尤拉函式定義} \end{aligned} $$ 好恭喜你可以在 $O(\sqrt n)$ 的優秀時間複雜度裡求得答案了! ### 4.3 實現 提示一下實現上的一些細節。 快速冪作為基本技巧就不提了; 尤拉函式直接質因數分解求即可。這裡會遇到一個小問題:外面一層列舉因數,裡面一層分解質因數,這不 $O(\sum_{d|n} \sqrt d)$ 了嗎? 實際上似乎利用數列的放縮之類的黑科技可以證明一個比 $O(n)$ 更緊的上界是 $O(n^{\frac 3 4})$ ,而且實際上跑起來非常的快。(洛谷 $n=10^9$ , $10^3$ 組資料可以隨便跑過) ```c++ /* 洛谷P4980 Polya定理 sun123zxy 樸素寫法 洛谷共2.08s 2019/12/24 */ #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; ll Rd(){ ll ans=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar(); return ans; } const ll MOD=1E9+7; ll QPow(ll x,ll up){ x%=MOD; ll ans=1; while(up) if(up%2==0) x=x*x%MOD,up/=2; else ans=ans*x%MOD,up--; return ans; } ll Inv(ll x){return QPow(x,MOD-2);} ll Phi(ll n){ ll t=n; ll ans=1; for(ll i=2;i*i<=t;i++){ ll c=0; while(t%i==0) t/=i,c++; if(c) ans=ans*(QPow(i,c)-QPow(i,c-1)+MOD)%MOD; } if(t>
1) ans=ans*(t-1)%MOD; return ans; } ll N; ll Polya(ll d){ return QPow(N,d)*Phi(N/d)%MOD; } void Solve(){ ll Ans=0; for(ll i=1;i*i<=N;i++){ if(N%i==0){ Ans+=Polya(i); if(i!=N/i) Ans+=Polya(N/i); Ans%=MOD; } } Ans=Ans*Inv(N)%MOD; printf("%lld\n",Ans); } int main(){ ll T=Rd();while(T--){ scanf("%lld",&N); Solve(); } return 0; } ``` 不過當然有真正 $O(\sqrt n)$ 的寫法。只需在最外層分解質因數,然後DFS的去列舉因數,這樣就不用每次去分解 $\frac{n}{d}$ 啦!於是這種寫法就當然比上面那種快很多了。 ```c++ /* 洛谷P4980 Polya定理 sun123zxy 更優寫法 洛谷共125ms 2019/12/24 */ #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; int Rd(){ int ans=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') ans=ans*10+c-'0',c=getchar(); return ans; } const ll MOD=1E9+7; ll QPow(ll x,ll up,bool isM=1){ x%=MOD; ll ans=1; while(up){ if(up%2==0) x=x*x,up/=2; else ans=ans*x,up--; if(isM) x%=MOD,ans%=MOD; } return ans; } ll Inv(ll x){return QPow(x,MOD-2);} namespace Div{ int p[30],c[30]; int pN; void Div(int nb){ pN=0; int t=nb; for(int i=2;1LL*i*i<=t;i++){ if(t%i==0){ p[++pN]=i,c[pN]=0; while(t%i==0) t/=i,c[pN]++; } }if(t>
1) p[++pN]=t,c[pN]=1; } } int N; ll Ans; void DFS(int pos,ll d,ll phi){ using namespace Div; if(pos==pN+1){ Ans=(Ans+QPow(N,d)*phi)%MOD; return ; } ll tpow=1,tphi=QPow(p[pos],c[pos],0)-QPow(p[pos],c[pos]-1,0); for(int i=0;i<=c[pos];i++){ DFS(pos+1,d*tpow,phi*tphi); tpow*=p[pos]; if(i==c[pos]-1) tphi=1; else tphi/=p[pos]; } } void Solve(){ Div::Div(N); Ans=0;DFS(1,1,1); Ans=Ans*Inv(N)%MOD; printf("%lld\n",Ans); } int main(){ int T=Rd();while(T--){ scanf("%d",&N); Solve(); } return 0; } ``` ## 5. 總結 對於大多數題目,Burnside & Polya通常是套在最表面的那一層皮,難點一般在求 $|C(f)|$ 或者 $f(\gcd(n,i))$ 的部分。 ## 6. 參考及後記 #### zkx / keke / 彳亍 學長的 《Polya計數.pptx》 整個PPT思路非常清晰,可以看出keke學長對Polya有極其深入的理解。我學Burnside完全是照著這個PPT一點一點的看懂的。 彳亍來講課的那個暑假可以說是真正讓我在OI數學這一塊有很多新的收穫。感謝keke學長! #### 《演算法導論》第三版 31.3節 模運算 初稿寫成後,在學習數論時偶然翻到這一節有對群的標準定義,發現自己之前的理解不夠優秀。遂做了一些訂正。 ~~我之前把交換群認成群瞭然後自己yy了一套理論xD~~ #### 一些想法 這大概是我最長的一篇部落格了.. Burnside & Polya 最開始是2019暑假zkx學長為我們講授。當時雲裡霧裡,半懂不懂。12月的時候有將近一半的同學跑去PKUWC/THUWC了,剩我這個菜雞在機房瞎頹(((當時就花了一兩天把zkx學長的PPT慢慢看懂了,做了最初的筆記。然後在接下來的幾個月裡修訂完善。現在用一天半的時間把筆記寫成了部落格,又有了些新的理解,增加了弱化版及其證明。 概念多,證明繞,很容易掉進思維的陷阱。如果能一步一步把證明過程捋清楚,對思維能力的提升還是很大的。 任何推導的目的都是由已知得到未知。由哪些性質推得哪些結論,好比圖論中的有向邊,最後應該形成一個有向無環圖。如果把這個DAG搞清楚了,才是真正弄清楚了結論的來龍去脈。 本文多次用到了“將等價類計數問題轉換為有多少個元素與某個確定的元素等價,並利用等價傳遞性匯出封閉性說明形成連通塊”這一思想,很具有推廣性。 OI裡的數學相關知識,都給人一種人類智慧的感覺,還是滿有意思的( 20