首先給出一些定義.
置換:是一個排列.含義是將另外一個排列進行重排操做.
若是記A[i]爲置換A的第i個元素,那麼對一個排列進行置換A這個操做,表示將原先第i個位置上的數字挪到第A[i]個位置.
例如,置換(3,2,1)表示將整個排列顛倒順序.置換(2,3,4,1)表示將每一個元素放到右邊相鄰的位置,最右邊的元素放到最左邊的位置.
置換之間定義了乘法.兩個置換A和B所帶來的效果至關於置換C帶來的效果,那麼AB=C.
例如,(2,3,4,1)*(2,3,4,1)=(3,4,1,2),每一個元素右移一個位置,進行兩次,至關於每一個元素右移兩個位置.
置換乘法知足結合律但不知足交換律.
問題1:n個白色珠子和n個黑色珠子能排列成多少種不一樣的線性序列?
C(2n,n)即爲答案.
問題2:n個白色珠子和n個黑色珠子能排列成多少種不一樣的線性序列?若是一個序列能夠經過不斷把最左側的珠子拿到右邊獲得另外一個序列,那麼這兩個序列是本質相同的序列.
這樣的問題稱爲等價類計數問題.題目中會定義一類等價關係,知足等價關係的元素被當作同一類,只統計一次.
要用咱們接下來描述的算法解決等價類計數問題,等價關係必須可以用多個置換組成的集合表示.若是集合中存在一個置換使得元素A變成元素B,那麼A和B等價.
這個集合必須知足對稱性,若是存在置換使得元素A變成元素B,就必須存在一個置換使得元素B變成元素A.
這個集合必須知足封閉性.集合中拿出兩個置換A和B,A*B=C,那麼C置換也必須在集合中.也就是說,若是咱們進行一種置換A使元素x變成y,一種置換B使元素y變成z,那麼集合中必須存在一種置換C使得x直接變成z.
這個集合中必須含有」單位元」,一個使得元素不發生變化的置換.也就是必須知足每一個元素和自身等價.
根據等價關係,全部元素能夠分爲若干個等價類,同一類的元素相互等價,不一樣類的元素相互不等價.
圓排列問題實際上就是一個等價類計數問題:記」旋轉」爲把排列的第一個元素拿到最後,因爲一個排列旋轉0,1,2,3,…n-1次獲得的結果必定不一樣,每一個等價類中都有n個元素,一共有(n-1)!個等價類.
可是對於更普遍的問題,不一樣等價類中的元素數目不必定相同.
例如,對於問題2,n=2的時候有兩個等價類,分別有2,4個元素.
0表示白色,1表示黑色.
0011,1001,1100,0110是一類
1010,0101是一類
咱們不妨寫個程序看看n=3的狀況
000111,100011,110001,111000,011100,001110是一類
110010,100101,001011,010110,101100,011001是一類
110100,101001,010011,100110,001101,011010是一類.
010101,101010是一類
輸出更多的狀況觀察一下規律?每一類的元素數目有什麼特色?
咱們能夠發現,對於總長度爲2n的序列,每一類的元素個數都是2n的約數.
假設某一類中含有m個元素,那麼從中任意選擇一個元素,不斷旋轉,必定能夠獲得所有m個元素.
咱們能夠用置換描述不一樣的旋轉操做:對於長爲n的序列,只能旋轉0,1,…n-1次.更多的旋轉次數必定和以前的某種次數是等價的,例如旋轉n+2次至關於旋轉2次.本題中,長度爲2n的序列,則有2n種置換.
對於集合中的一個置換f,若是某個元素被f操做後和原先相同(不只本質相同並且」看上去」也相同),那麼稱這個元素是f的一個不動點.
能夠證實,等價類的數目就是全部置換的不動點數目的平均值.證實在最後.
那麼對於這個問題,就是對旋轉0,1,2,…2n-1次分別求出這個狀況下」不變」的元素數目.
旋轉0次不變的元素數目即爲C(2n,n),任何一個元素都和自己同樣.
旋轉1次不變,則任意兩個相鄰位置的顏色相同,故不存在合法解.
旋轉2次不變,那麼奇數位置都相同,偶數位置都相同,有2種.
旋轉m次不變,那麼記G=gcd(2n,m),G,2G,3G…這些位置都相同,1,G+1,2G+1…這些位置都相同,所以咱們只須要考慮前G個位置如何排列.只有當G爲偶數的時候有C(G,G/2)個不動點.算法
如何證實等價類的數目就是全部置換的不動點數目的平均值?
(這個證實要求涉及的置換知足交換律,好比每一個置換都是」旋轉k次」的狀況)
假設有n種置換,考慮某一個等價類,其中含有m個元素.假設對於其中某一個元素s1,把n個置換分紅兩類,有x種置換使得它變成它自己,y種置換使得它變成另外(m-1)個元素中的一個.x+y=n.
根據以前的定義,n種置換中存在一個單位元i使得一個元素變成和它相同的元素,那麼這個置換i乘上另外一個置換A必定還獲得置換A.在以前分類的時候,i必定被分到前x種內.
首先咱們證實對於這個等價類中的每一個元素,x,y的數值是相同的.
假設s1,s2是這個等價類中的兩個元素.必然能夠找到一個置換A使得s1*A=s2,一個置換B使得A*B=i.
(若是置換A是」將長度爲n的序列旋轉k下」,那麼置換B就是」將長度爲n的序列旋轉n-k下」)
s1*C=s1,s1*A=s2,gc
故s1*C*A=s2,s1*A*C=s2(這裏使用交換律),程序
s2*C=s2.統計
也就是,置換C知足s1*C=s1(使s1變成相同的元素),那麼必定知足s2*C=s2.集合
反過來,若是置換C知足s2*C=s2,那麼必定也知足s1*C=s1,數字
所以對於s1和s2,使這個元素不變的置換的數目x是相同的,並且都是一樣的x個置換,組成集合S.枚舉
針對元素s1,s2,咱們必定剛好有x個置換使s1變成元素s2.gcd
任取一個能使s1*A=s2的置換A,而後枚舉S中的置換B,一共獲得x個不一樣的A*B(其中包括A自己),顏色
這x個A*B的結果對應的置換都可以使得s1變成s2.
有m-1個除了s1以外的元素,那麼y=(m-1)x,n=mx
每一個元素都會在x種置換中貢獻一個不動點,一共貢獻了n個不動點,最後還要除以n,
因此每一個等價類對答案貢獻了一個1,正是咱們須要的結果.