Burnside引理和Pólya计数法

来源:互联网 发布:中国警察智识数据库 编辑:程序博客网 时间:2024/06/02 13:14

这是一篇我阅读论文《Pólya计数法的应用》以及做了若干有关题目的心得,用于备忘,借以纪念那些苦苦思索的时光。

重要提示:本文禁止任何形式的转载。若你觉得本文对你有帮助,你可以与别人分享,但不允许上传到各文库平台。

提示:阅读本文可能(不)需要一些组合数学的基本知识。

提示2:本文可能过于冗长,只对关注的部分内容进行阅读是明智的选择。


定理和公式的推导

推荐:Combinatorics (Fifth Edition), Richard A. Brualdi,阅读原书以获得更愉快的学习体验。

定义1:函数(略)

定义2:排列(置换)

wiki上说Permutation有两种等价的定义,我们这里取前一种(active)说明,即一个集合X的排列P是一个从XX的双射函数。用符号和英文装13一下就是

P:XX,P is bijective

由于双射这个强有力的限制条件,这个定义和我们平时所理解的排列,即wiki说的第二种(passive)定义是完全等价的。之所以用如此高深的术语,是因为函数的引入对我们后续的分析会带来极大的帮助。

鉴于这个主题下研究的对象都是自然数,我们令X表示集合{1,2,,n},用Sn表示集合{1,2,,n}所有的排列组成的集合。

不过这个定义看起来还是有点玄乎,我们用一个2×n的数组来表示排列P

P=(1i12i2nin)
下方的i1in就是通常意义下我们理解的排列,这里强调了它是一个函数。即P(k)=ik(k=1,2,,n)

和普通的函数一样,排列也可以复合。令f,gSn,其中

f=(1i12i2nin)
g=(1j12j2njn)
其复合
gf=(1j12j2njn)(1i12i2nin)
满足(gf)(k)=g(f(k))=jik

复合运算满足结合律,即(fg)h=f(gh),但不满足交换律。我们引入幂运算符号表示排列的复合,如下所示:

f1=f,f2=ff,f3=fff,,fk=fff(kf)

定义恒等排列ι,即
ι=(1122nn)

根据定义显然有ιf=fι=f

fSn,因为它是一个双射函数,因此存在反函数f1,而且f1Sn,满足f1(k)=sf(s)=k。根据定义我们不难得到ff1=f1f=ι。另外,定义f0=ι。(这个定义是必要的,因为根据前面所有的内容,我们没有得到f0的方法)

定义3:置换群

集合X的置换群G定义为

GSn,satisfies(1)f,gG,fgG(2)ιG(3)fG,f1G

不难看出,这三条对应着封闭性、单位元和逆元的存在性。(事实上,群要求运算满足结合律,但是因为函数的复合自然地就满足结合律,因此我们不特别地提出)特别地,Sn本身也是置换群,我们一般将其称为n对称群

对于置换群,满足消去律(这个消去律很有用),即

fg=fhg=h
推导如下
fgf1(fg)(f1f)gιgg=fh=f1(fh)=(f1f)h=ιh=h

我们以一个排列ρn为例,研究一下排列和置换群的性质。定义
ρn=(122334n1nn1)

这个排列很有规律,可以看作是对把从1n的整数排成一圈再旋转1n周得来。根据这个排列的含义容易看出
ρkn=(1k+12k+2nknnk+11nk)
而且特别地,
ρnn=ρ0n=ι,ρ1n=ρn1n
我们发现,
k{0,1,,n1},(ρkn)1=ρnkn()
而且,
ρrn=ρkn,ifrk(modn)
也就是说,
i,j{0,1,,n1},ρinρjn=ρi+jn=ρ(i+j)modnn()

当然,单位元ι也是存在的,因此集合{ρ0n=ι,ρn,ρ2n,,ρn1n}是一个置换群。

定义4:染色

提到Burnside引理就不得不先提到染色的概念。
我们先假设集合X={1,2,,n}GX的一个置换群,那么X的一种染色就是一种把X中的每个元素分配上一个颜色的方案。令cX的一种染色,然后把1,2,,n的颜色记为c(1),c(2),,c(n),对于fG,而且

f=(1i12i2nin)

定义fc是一种染色满足(fc)(ik)=c(k),(k=1,2,,n),一种等价的表示是(fc)(l)=c(f1(l)),(l=1,2,,n)(请反复阅读这段定义,甚至举例,直到彻底明白这个定义的含义)

为了更好地理解这个奇怪的运算,我们证明一个等式(gf)c=g(fc)

((gf)c)(k)=c((gf)1)(k)=c(f1(g1(k)))(g(fc))(k)=(fc)(g1(k))=c(f1(g1(k)))

定义5:等价染色

终于,我们可以定义等价染色了。
GX={1,2,,n}的一个置换群,令C包含若干个X的染色的集合(不需要是全部染色的集合),满足fG,cC,fcCc1,c2C。我们定义C上的一个二元关系,若fG,fc1=c2,则c1c2。下面我们证明这是一个等价关系。

(1)自反性:cC,cc(ιc=c)

(2)对称性:c1c2c2c1(fc1=c2f1c2=c1)

(3)传递性:c1c2,c2c3c1c3(fc1=c2,gc2=c3(gf)c1=c3)

因此,是等价关系。这里等价的定义确实非常学术,然而这个等价和我们平时所认为的等价又确实是等价的。我们回过头看这个二元关系的定义,置换群的排列相当于我们定义的变换操作,如果一种染色在某种排列的变换下得到另一种染色,显然它们就是等价的。


Burnside引理

定义6:令G(c)表示置换作用下c保持不变的置换集合,即

G(c)={f:fG,fc=c}

定义7:令C(f)表示置换f作用下保持不变的染色集合,即

C(f)={c:cC,fc=c}

我们计算所有满足fc=c(f,c)有序对的数量,于是发现
fG|C(f)|=cC|G(c)|

我们先证明一个定理

定理1:c,G(c)是一个置换群f,gG,gc=fcf1gG(c)

证明:

(1)封闭性:fc=c,gc=c(gf)c=g(fc)=c

(2)单位元:ιc=c

(3)逆元:fc=cf1c=f1(fc)=c

因此G(c)确实是置换群

接下来我们证明定理的第二部分,先假设fc=gc,于是

(f1g)c=f1(gc)=f1(fc)=(f1f)c=ιc=c
(这里我们用到了前面的一个结论)因此
f1gG(c)
再假设f1gG(c),则
(f1g)c=f1(gc)=c

另一方面,
f1(fc)=(f1f)c=c
由消去律就得到
fc=gc

然后根据这个定理我们得到一个推论

推论1:令cC,则所有与c等价(当然,包括自身)的染色数等于置换群G的大小除以在置换作用下c保持不变的置换集合的大小,即

|{fc:fG}|=|G||G(c)|

证明:令f,gG,且gc=fc。根据定理1
f1gG(c)
h=f1g,因此
g=(ff1)g=f(f1g)=fh
也就是说
g{fh:hG(c)}
由于置换群满足消去律,我们可以得到
fh=fhh=h
那么
|{fh:hG(c)}|=|G(c)|
这个式子的含义是,有且仅有|G(c)|种排列,它们的置换作用在c上和排列f作用在c上是相同的。另一方面,排列总数是|G|,我们已知|G(c)|种排列对c作用得到的染色都是相同的,因此得到的不同的染色有|G||G(c)|种,也就是说,和c等价的染色一共有|G||G(c)|种。
为方便起见,我们记和c等价的染色数为e(c),即e(c)=|G||G(c)|

定理2:Burnside引理

GX的置换群,C是满足前述条件的染色集合,那么在G中排列定义的变换下本质不同的染色数

N(G,C)=1|G|fG|C(f)|

证明:由推论1,我们得到
|G(c)|=|G|e(c)
因此,
cC|G(c)=|G|cC1e(c)
因为和c等价的染色有e(c)种,这些染色对求和项的贡献正好是e(c)×1e(c)=1。所以
cC1e(c)=N(G,C)
因此
cC|G(c)|=|G|×N(G,C)
我们之前得到了
fG|C(f)|=cC|G(c)|
因此
N(G,C)=1|G|fG|C(f)|
这就是我们梦寐以求的Burnside引理。
现在,有了Burnside引理这个有力的武器,我们要做的就是对每一种置换,找出有多少种染色在该置换的变换下保持不变,代入公式就可得到所有本质不同的染色数了。


不过,如果我们对每种置换直接枚举所有的染色,再检验其是否在置换下保持不变,往往复杂度过高,难以承受。(假设置换数是G,染色数是p,置换的长度(集合的大小)是n,那么时间复杂度是O(Gpn)
首先,我们考虑能否高效地找到每种置换下有多少种染色是不变的。

定义6:排列的循环表示

fX={1,2,,n}的一个排列,有向Df=(X,Af),其中边集Af={(i,f(i):iX}。显然这个图有个n个点和n条边,而且每个点入度和出度都为1。可以证明,每个点都属于唯一一个有向环中。因此我们就可以把排列写成若干个循环组成的形式。这里不得不举个例子

f=(142135425366)=(142)(35)(6)=(35)(6)(214)
值得注意的是,各个循环之间和循环内部元素之间都没有先后次序,但是在循环内部元素的次序一定满足前一个元素指向后一个元素(最后一个元素指向第一个元素),构成一个有向的环。

引入排列的循环表示有什么用呢?不难看出,对于任意一种排列,如果要求染色在这种置换下保持不变,当且仅当在同一个循环中的元素染成相同的颜色。拿上面的例子来说,就是编号为1,2,4的元素必须染成同一种颜色,编号为3,5的元素必须染成同一种颜色,编号为6的元素必须(当然)染成同一种颜色。道理很简单,置换对染色的作用结果是把一个点的颜色变为所在循环中的上一个点的颜色,如果同一个循环中的元素染色不全相同,那么变换之后这种染色就无法保持不变。
我们将排列f的循环个数记为(f),那么自然就得到如下的定理

定理3:令fX的一个排列,CX的所有染色组成的集合。若我们有k种颜色可用于染色,则有

|C(f)|=k(f)
结合上定理2,就得到
N(G,C)=1|G|fGk(f)

不过这只是Pólya计数法的简化版本,但这个简化版已经足够解决很多问题了。


题目解析和技巧

sgu294 He’s Circles
论文的第一道题,题意很简洁,就是对长度为n的环,仅考虑循环同构下求本质不同的染色数。虽然我们已经有了计数,但单纯是构造所有的置换(有n个循环的置换)求出其循环个数(至少也要O(n)dfs)就是O(n2)的时间复杂度,怎么办呢?

考虑旋转k个元素的排列ρkn

ρkn=(1k+12k+2nknnk+11nk)
哪些元素和1号元素处在同一循环中呢?设m号元素和1号元素在同一个循环,那么
m=(1+p×k)modn
变换一下
m+q×n=1+p×k
g=gcd(k,n),那么gk,gn,于是
m1(modg)

所以,所以模g同余的数都处在同一个循环中,因此总共有g个循环,每个循环有ng个元素。这样我们就可以O(n)1n扫过去求出当前数与n的最大公约数然后快速幂就可以解决了。

如果你以为这样就可以解决这个问题,那就naive了,因为这个题并没有要求答案模一个数,就是说,需要高精度。然而,由于这个n实在是太大了,最终答案好几万位,如果按照我们刚才的做法是会T的(至少我T了,也许是高精度常数太大了,如果你对自己的代码实现有信心不妨一试),我们需要进一步的优化。

显然,i{1,2,,n},gcd(i,n)的值只可能是n的约数,一个数的约数是不多的,至多是O(n)数量级的,问题就剩下如何很快知道i{1,2,,n},gcd(i,n)=k的数有多少个了。

先考虑一个特殊情形,k=1,这时我们要求的就是1,2,,n中和n互质的数有多少,我们知道,这就是欧拉函数φ(n)的值。但是k1时怎么办?

Ak={i{1,2,,n}:gcd(i,n)=k}Bk={i{1,2,,nk}:gcd(i,nk)=1}。我们把Ak中的元素都除以k,这时这些数就和nk互质,因此|Ak||Bk|。另一方面,我们把Bk中的数都乘上k,显然这些数就满足和n的最大公约数为k,而且乘积仍然不大于n,因此|Bk||Ak|。综上所述,|Ak|=|Bk|=φ(nk)

因此我们可以O(n)枚举n的约数,统计有多少种置换是以这个数作为循环个数,计算出最后的答案。具体实现的时候可以用线性筛法,顺便预处理出从1n欧拉函数加速计算。
(使用Java的BigInteger,代码更简洁)

poj2409 Let it Bead
和上一题相比多了反射同构的限制,不过这道题数据范围极小,强行构造O(n2)应该是可行的,但这显然不是我们追求的目标。

我们分奇偶讨论:
(1)若n为奇数,那么反射的对称轴一定经过一个珠子的中心,经过轴的珠子自身构成一个循环,其他的珠子两两构成一个循环(自行脑补反射图形),因此总共有n12+1个循环。这样的反射变换有n种。

(2)若n为偶数,那么反射分为两种,一种对称轴经过两条相对的边,珠子两两构成一个循环,总共有n2个循环,这样的变换有n2种;另一种对称轴经过两个相对的点,这两个珠子分别构成一个循环,其他珠子两两构成一个循环,总共有n22+2个循环,这样的变换也有n2种。
这样我们就直接得到了所有反射变换的情况。

poj1286 Necklace of Beads
从两种颜色变成三种有本质区别吗?我想大概是没有。

hdu3923 Invoker
这次颜色数目不定了,然而还是没有本质区别。
这题要求答案模一个质数,乘法加法操作还好说,最后我们有一个除以2n的除法操作,改成乘上逆元即可。模数是质数时求逆元直接用费马小定理即可。

poj2154 Color
只有旋转变换,但是n非常大,必须要用之前所述的欧拉函数优化,而且欧拉函数只能O(n)现求,因为开不出那么大的数组。最后要求答案模一个数,不保证是质数。乍一看还不太好处理(但确实可以处理,后面会介绍一种奇妙的方法),然而这题的颜色数也是n,我们可以在处理n的幂次时直接减1即可。

uva11255 Necklace
这道题只有三种颜色,但是对每种颜色的数目进行了限定。我们介绍两个方法。
(1)记fijk表示在当前置换中用了i个白色,j个灰色,k个黑色珠子的染色方案数,把每个置换的fabc累加,再除以2n就是答案。
(2)如果某种排列下,所有的循环长度都是相同的值k,显然,a,b,c都必须是k的倍数,否则无解。在这个前提下,我们把一个循环看作一个整体,令a=ak,b=bk,c=ck,n=a+b+c,现在问题就转化为有n个珠子,要把a个珠子染为白色,b个珠子染为灰色,c个珠子染为黑色,求方案数。这是一个可重复排列问题,答案为n!a!b!c!。对于旋转变换,所有的循环长度都是相同的;然而反射变换的情况下有一一个点单独为一个循环的情况,我们只要枚举这个点的颜色并除掉这个点即可。

bzoj1004 [HNOI2008]Cards
这题置换是题目给定的,因此需要手动处理一下循环的大小和个数。然后用上一题的方法(1)求解即可。

hdu1812 Count the Tetris
这题计算的是n×n方格本质不同的染色数。分奇偶讨论旋转和反射变换即可。

poj2888 Magic Bracelet
这道题要求某些珠子不能相邻,这样限制了一下我们就不能用,而是要直接用。前面我们已经分析,对于旋转k个珠子的变换ρkng=gcd(k,n),有且仅有g个循环,而且不难发现1,2,,g分别属于不同的循环,也就是说,确定了1,2,,g所属的颜色,就能构造且仅能构造出一组在ρkn作用下不变的染色,而且,如果1,2,,g染色是合法的,那么其他位置的染色也是合法的。我们现在只要确定有多少种可行的1,2,,g的染色然后累加即可。

我们构造一个邻接矩阵A,其中

Aij={1,0,if i, j can be adjacentelse
根据矩阵相乘的意义,Agij就表示从起始珠子的颜色是i,结束珠子的颜色是j,总共有g+1个珠子的方案数。那么对于置换f=ρkn,我们有
|C(f)|=i=1mAgii

这里为什么是mi=1Agii呢?因为珠子1g+1属于同一个循环,需要染成同一种颜色,也就是说,珠子g1也要满足限制条件,相当于要展开成了1,2,,g,1的序列,其实就是一个1,2,,g的环。顺便说一句,这就是矩阵Ag的迹tr(Ag)
提示:9973是一个质数。

hdu2865 Birthday Toy
这道题要求相邻的珠子不同色。如果颜色数少的话,我们完全可以按照上一题的模式求解,但是这题的颜色数非常多,并不能开出如此大的矩阵。不过这道题的限制是有规律性的,可以直接从矩阵中推导出公式,但我们下面要介绍的是一种递推的方法。

fi表示i个元素的环(不妨设元素依次为1,2,,i)有多少种合法染色数。假设现在我们有k种颜色可用,那么我们枚举第i1个元素的颜色

(1)i11同色,这样的方案相当于在i2个元素的环中插入i1,而且i可选k1种颜色。

(2)i11异色,即1,2,,i1构成i1个元素的环,那么i可以选k2种颜色。

因此fi=(k2)fi1+(k1)fi2,不过i=1,2时我们还没有定义。

对于循环个数为g的情况,和上一题同理,保持不变的染色数就是fg。考虑g=1的情况,这意味着所有的珠子都要染成同色,显然不合法,令f1=0。至于g=2,显然有f2=k(k1)。这样我们就可以枚举n的所有约数计算了。

然而n也是非常大,我们无法预处理从1n所有的f,临时计算是O(n)的,也不满足要求,这怎么办?因为fi仅仅和前面两项有关,而且系数是常数,因此这个递推关系可以用矩阵快速幂优化,这样就可以解决了。(这个递推似乎可以用简单代数方法直接求出通项公式,这样直接快速幂应该也是可以解决的)

hdu3547 DIY Cube
这道题求对一个立方体的顶点染色,旋转同构下本质不同的染色数。

为了解决这道题,我们需要先研究一下立方体的旋转变换。首先我们分析一下立方体有多少种旋转变换。

假想把立方体放在平面上,首先选择一个面作为底面,这就有6种选择;然后在4个侧面中选择一个作为前面。这样我们就确定了一种立方体的形态。因此我们就知道,立方体一共有6×4=24种不同的旋转变换。接下来我们要对这些变换分类。

(1)不动变换,显然只有1种。

(2)以任意两个对面的面心为轴旋转90,180,270,一共有3×3=9种。

(3)以任意两个对边的中点为轴旋转180,一共有6×1=6种。

(4)以任意两个对点为轴旋转120,240,一共有4×2=8种。

对这道题来说,(1)的情况有8个循环;(2)的情况下,902702个循环,1804个循环;(3)的情况有4个循环;(4)的情况有4个循环。(强烈推荐自己动手推导一下,有助于加深理解)

我们可以直接推导出公式。设颜色数为k,答案就是k8+17k4+6k2,需要用高精度。

uva10601 Cubes
这道题也是有关立方体的。不过这次我们关注的是边的染色,而且限定了每种颜色的数量。和上一题类似,我们需要对4种旋转情形分别进行讨论。得到每个循环的大小后,采用上面uva11255 Necklace的给出的两种方法中的任意一种进行计算即可。

hdu2481 Toy
这道题要求对一个特殊的点数为n+1,边数为2n的图,求旋转同构下本质不同的生成树个数。

这道题不是我们熟悉的有关染色的题目,乍一看无从下手。不过我们可以这样看:一条边若在生成树中,我们就视其染为黑色,否则视其染为白色,那么一个生成树就对应一个合法的染色方案,而且本质不同的生成树就相当于本质不同的染色方案。我们要求的结果就是本质不同的合法的染色方案的数目。而且这里的旋转变换和一串珠子的旋转变换是类似的(考虑中间的n条边,在旋转变换下可以视为一个环,至于外围的n条边,本身就构成环)。

令外围的点依次为1,2,,n,中心点为n+1。对于旋转k个点的变换ρkn,令g=gcd(k,n),我们可以把外围的点按顺序分为大小为gng块。我们考虑第一块的g个点(即1,2,,gg个点)和中心点构成的导出子图,这个导出子图有g+1个点,2g1条边。我们再把gg+1之间的边添加到图中,现在我们的图中就有2g条边。用类似操作我们完全可以得到没有公共边的ng个这样的图,即我们把边集划分为ng个子集合。容易看出,这些边集是同构的;而且,要使染色保持不变,当且仅当每个边集都进行同样的染色。也就是说,考虑使染色保持不变的前提下,我们确定了第一个边集的染色,其余边集的染色就是确定的了。现在的问题就是,有多少对这样构造出来的边集的染色是合法的?

不难发现,在这个旋转变换下,g+11实际上是等价的,我们连的gg+1的边也相当于n11所连的边,因为n1g也是等价的。gg+1的边其实等价于g1直接相连。这样我们发现,每个小边集其实和点数为g,边数为2g的问题是完全相同的。如果选取该边集中的边染色形成一棵树,并对其余边集进行相应染色,那么整个大图就是一棵树;反之亦然(这里我实在是难以用数学语言表达)。

fi表示点数为i的图的生成树个数,那么根据上述分析,结合Burnside引理,我们得到我们要求的结果是(注意我们求的并不是fn

ni=1fgcd(i,n)n

当然我们可以用欧拉函数加速。不过更重要的问题是,如何求fi
在这里我会给出两种方法。

(1)第一种是基于动态规划思想。我们先在外圈上任意取相邻的两点a,b,不妨令a1号点,bn号点,其余的点也依次顺序编号。令gn表示外圈有n个点时,a,b没有直接相连边时的生成树个数。假设恰有k个点(包括a自身)和a在外圈上直接相连(即1,2,kk个点相连,k+1k之间没有直接相连的边),可以看出这k个点中必然有且仅有一个点和中心点相连,否则就无法构成树结构。至于剩下的点,我们先删去1,2,,kk个点,其余外圈上的点就构成了nk个点的圈,而且1k+1之间不能连边。这样的方案数就是gnk。考虑到之前k个点中任意一点向中心点连边都是可行的,因此(这个式子n0才成立,当n=0时我们定义g0=1

gn=k=1nk×gnk

另一方面,令hn表示外圈有n个点时,a,b直接相连边时的生成树个数。同样,我们假设有k个点和a在外圈上直接相连,不过这次的点就不是1,2,k了,因为这次包含了b,这k个点有可能与b相连。但我们知道,a,b在这k个点中的位置有k1种可能。而且,这k个点也必然有且仅有一个点和中心点相连,剩下的点也可以看作是nk个点中有两个相邻点不能连边的情况,即gnk,所以(这个式子要求n2才有意义,我们定义h0=h1=0
hn=k=2nk×(k1)×gnk

不过我们现在的式子还不能直接用来计算,还需要进一步简化。
sn表示nk=0gk,因为
gn=k=1nk×gnkgn1=k=1n1k×gnk1=k=2n(k1)×gnk=k=1n(k1)×gnk

相减可得
gngn1=k=1n1gnk=sn1=gn1+sn2=gn1+(gn1gn2)
所以(这个式子要求n3
gn=3gn1gn2

再考虑hn,我们用相同方法得到
hnhn1=k=2n2(k1)gnk=2gn1
迭代累加可得
hn=k=0n12gk2g0+h1=2sn12=2gn2gn12

因为fn=gn+hn,而gnhn都能通过矩阵快速算出,这样问题就解决了。

(2)上面的推导确实繁琐了一些,也许我们有更加简洁的方法。
我们要求的是一个特殊构造图的生成树的个数。如果你看过我之前写的文章,或者之前已经掌握Matrix-Tree定理的话,我们只需要对下列n+1阶矩阵求一个n阶主子式

310111310101301100311111n
我们不妨就取前n行前n列构成的主子式,即我们要求
3100113100013000003110013
虽然形式上很有规律,不过这个行列式似乎还是不太好求。利用行列式的性质,我们对第一行拆分,将其变为(下面的过程不显示注明矩阵的阶数)
3100113100013000003100013+0100103100013000003110013
然后对左边的行列式的最后一行拆分,对右边的行列式按第一行展开,得到
3100013100013000003100013+3100113100013000003000010+(1)n1×(1)×1000131000131000001000031
再展开几步
3100013100013000003100013+(1)n1×(1)×1310001300001000001300001+(1)n×(1)×1000031000131000001000031+(1)n2×(1)×3100013100013000001300031
最后得到的式子是
3100013100013000003100013+(1)n×(1)n1+(1)n×(1)×(1)n2+(1)n1×3100013100013000001300031
我们令An表示n阶行列式
3100013100013000003100013
那么最后我们化简得到的式子是
AnAn22
于是现在我们只要快速求出An就行了。只要我们对第一行(或第一列)展开,不难发现An=3An1An2。有了这个递推关系,我们就可以构造矩阵或者直接求出通项求得An了。

最后要说的是,这道题要求答案模一个数m,但不一定是质数。很有可能要除的数n关于m不存在逆元,这就难办了。
不过我们可以证明一个式子

anmodm=amod(n×m)n
其中保证na
证明:根据数论基本知识,我们有
an=p×m+q
其中0q<m,两边同乘上n得到
a=p×(m×n)+q×n
因为0q<m,所以0q×n<m×n,即
amod(m×n)=q×n
所以
anmodm=qamod(n×m)n=q
故结论成立。
所以我们就可以改为模n×m,最后直接除掉n即可。不过这样一来模数就达到1018,两数相乘很有可能超过long long范围,需要用二分乘法以避免溢出。

spoj419 Transposing is Fun
spoj422 Transposing is Even More Fun
这两道题题意是相同的,差别在于数据范围。如果我们把矩阵元素的地址用二进制表示连在一起就会发现,转置后相当于整个二进制数循环右移了b个单位(等价于循环左移了a个单位)。

我们构造一个2a2b的排列,转置后的元素地址作为排列函数的值。显然,对于排列中的循环,显然我们一定是对循环中的元素进行交换才能最优,而且,如果循环的大小为x,那么我们需要进行x1次交换。也就是说,每有一个循环,我们的答案就要减1。假设总共有k个循环,那么答案为2a2bk。(不得不指出,论文此处打错了,让我思索了好久)

我们的目标就是要求这个排列中循环的个数。如果我们定义置换群为进行若干次循环右移变换的排列所组成的集合,那么在循环中的元素都是等价的,循环的个数就等于本质不同的序列数。现在我们只需要求在这个置换群下本质不同的长度为a+b的01序列的数量,这就可以用Pólya计数法了。

我们之前已经知道旋转k个元素的排列ρkn,循环数是gcd(k,n),这里我们可以类似地得到,k次循环右移的排列,循环数是gcd(k×b,a+b),一共有a+bgcd(b,a+b)个循环(经过lcm(b,a+b)b=a+bgcd(b,a+b)次变换必然会到初始状态),令g=gcd(b,a+b),那么这种排列下保持不变的染色数为2gcd(k×b,a+b)。把各个排列的结果累加再除以置换个数,问题就基本解决了。

有些另外的题解表示的染色数形式是2g(gcd(k,a+bg)),和我们得到的不太一样;然而我们可以推导出这个形式。因为gcd(k×b,a+b)=g×gcd(k×bg,a+bg)。因为bga+bg,而且bga+bg互质,由数论知识我们可以直接将其消掉,所以染色数也可以表示为2g(gcd(k,a+bg))

然而spoj422并没有那么好过,由于a+b非常大,而且数据组数也非常大,时限却又非常紧,即使我们采用预处理出欧拉函数优化依然会T。我们需要更加强力的优化措施。我们不再采用O(n)枚举约数的方法,转而直接构造出n的约数。具体实现时,我们先对n进行质因数分解(鉴于这道题a+b还不是特别大,我们可以在做线性筛法时顺便求出每个数最小的质因数,然后分解就方便了),然后记录每一个质因数的值和它的幂次,用dfs强行构造出所有约数再进行计算。

sgu282 Isomorphism
一个无向完全图,对边染色,求本质不同的染色数。
这是论文的最后一道题,也确实是非常神的一题。这道题置换是和点有关的,但染色却是对边的。我们考虑如何从一个关于点的置换推导出对应的关于边的置换的性质。
对其中任意一条边,两个点要么处于同一循环(点置换),要么分别处于不同的循环。我们分别对这两种情况进行讨论。

(1)两个点处于同一循环。不妨设循环的长度为l,我们用排列的循环表示列出这个置换。

(a1a2al)
也就是说,点置换的顺序是a1a2ala1。现在我们枚举k{1,2,,l1},我们发现i,j{1,2,,l1}ai,a(i+k)modlaj,a(j+k)modl属于同一循环。这样我们就可以把所有的边分为l1个循环。另一方面,ai,a(i+k)modla(i+k)modl,ai是同一条边,而a(i+k)modl,aiai,a(i+(lk))modl在同一循环。所以k=tk=lt的情况下对应的是同一个循环,可以合并。
因此我们就得到,当l是偶数时,循环有l12+1=l22+1=l2=l2个;当l是奇数时,循环有l12=l2个。综上,边循环有l2个。

(2)两个点分别处于不同的循环。不妨设两个循环的长度为l1,l2,显然,第一个分量回到自身需要l1次变换,第二个分量回到自身需要l2次变换,那么回到原来的边就至少需要lcm(l1,l2)次变换,即这个循环包含lcm(l1,l2)条边。而满足前提的边有l1×l2条,因此这种情况下就有l1×l2lcm(l1,l2)=gcd(l1,l2)个循环。

可以看出,边置换的循环个数只和点置换各个循环的大小决定。确切地说,假设一个关于点的置换,有m个循环,每个循环的大小分别为l1,l2,,lm,那么边置换中的循环个数就是关于l1,l2,,lm的函数。因为点置换中各个循环大小之和显然是n,因此我们只要对n进行正整数拆分,每种拆分就对应一类点置换(每个拆分出来的数代表点置换中一个循环的大小),这些点置换对应的边置换的循环个数都是相等的。然后我们就可以应用上面的结论,计算边置换中的循环个数了。(具体实现的时候,dfs强行拆分n即可)

不过还有一个问题,就是对于某种特定的拆分,有多少种点置换对应呢?首先,仍然假设有m个循环,每个循环的大小分别为l1,l2,,lm。那么我们先要把n个点分配到这m个循环中,这有n!l1!l2!lm!种方式。对于长度为l的循环,一共有l!种排列,但是对于每种排列,有l种排列(包括自身)是与其等价的(考虑把这个排列循环右移l次),因此要乘上(l11)!(l21)!(lm1)!。最后,我们假设有t种不同的循环长度,每种长度有k1,k2,,kt个。对于第i种长度,把每个循环视为一个大的元素,这ki个大元素的任意排列都是等价的(这是显然的,因为循环之间没有先后顺序),所以要除掉k1!k2!kt!。因此最后我们得到的置换个数是n!l1l2lmk1!k2!kt!

提示:边置换的总数和点置换是相同的(一种点置换对应一种边置换)

提示2:答案需要模一个数PP保证是质数。

1 0
原创粉丝点击