排列(置换群Polya定理)_成型笔记
JueFan 一只绝帆

排列(置换群 Polya定理)

在通常的理解中,置换是一个元素两两不同且长度与值域大小相同的数组,但将置换看作“可运算的元素"是更本质的理解。

  • 定义 aba*b 这个运算得到的排列为满足 i,pi=bai\forall i,p_i=b_{a_i} 的唯一排列 pp

类似于将 aa 这个排列过了一遍 bb 这个”混淆器“,将原本的 aia_i 全部变成了 baib_{a_i}

类似的,我们有逆排列和元排列的定义:

  • 元排列 ee 有且仅有一个:1,2,,n1,2,\dots,n,元排列的性质是 a,ea=ae=a\forall a,e*a=a*e=a
  • 逆排列 a1a^{-1} 表示满足 aa1=a1a=eaa^{-1}=a^{-1}a=e 的唯一排列,可以证明每个排列都有逆排列,构造方式是逆排列满足 ppi1=ip^{-1}_{p_i}=i
  • e1=ee^{-1}=e

将其理解成矩阵的乘法即可,很多性质都可以套用,例如其满足结合律却通常不满足交换律。

置换和矩阵都是描述变换的,只不过置换描述的是变成了什么,而矩阵描述的是变成哪个元素的几倍。

有的时候我们只想要描述变成了什么,也可以称为一种广义的“置换”,这常用在数据结构中,来看例题:

CF911G Mass Change Queries

给定一个序列 aa,每次区间修改把 [l,r][l,r] 内等于 xx 的数变成 yy,问最后的序列。

n2×105,x,y,ai100n\le2\times10^5,x,y,a_i\le 100

这道题有其他更优秀的做法,但这里提供一种置换的简单做法。

考虑线段树,每个 tag\text{tag} 大小是 100100,维护每个数变成了什么,由于线段树 tag\text{tag} 有一个性质是两个 tag\text{tag} 合并的时候下面的 tag\text{tag} 是先打上的,所以下传是朴素的。

P8969 幻梦 | Dream with Dynamic

给定序列,要求支持区间加,区间取 popcount,单点查。

n105n\le 10^5

不难发现取完 popcount 之后的有效原值只有 6464,所以我们找到第一次取 popcount 的时刻,那之后就只需要维护 6464 个值分别变成了什么。

所以我们的 tag 里面需要有 ll ad,to[64];bool b;b 代表有没有进行过 popcountb=0 时只有 ad 有用,代表区间加了多少,b=1 时表示区间里的数先加了 ad 然后又做了一次 popcount,最终的值是 to[ppct(x+ad)]

Ex:需要支持区间求和?

线段树不大好搞了,考虑分块。

依然是每块维护同样的信息,没有 popcount 都好说,有的话就顺便维护一下每个数的出现次数即可。

其实以上两道题利用了区间维护的信息本质不多的原则,类似的可以用线段树求 n=100,m=105n=100,m=10^5 的区间最小生成树。

P4119 [Ynoi2018] 未来日记

给定序列,需要区间替换,区间 kth\text{kth}

n105n\le 10^5

毒瘤数据结构,抽空补。

置换的图论形式

在一个排列中,你可以 i[1,n],\forall i\in[1,n],iiaia_i 连一条边。

每个点恰有一条入边和出边,不难发现,这是若干个环组成的图。

这张图有很良好的性质,来些例子:

NFLS 2023.11.11 B

给定两个排列 a,ba,b,定义一次操作为随机选三个数轮换,问在 mm 步内把 aa 变成 bb 的概率。

n14,m109n\le 14,m\le 10^9

运用图同构的知识,我们可以知道只要两个置换的图同构,那对一个排列进行轮换,另外一个排列总能找到一种对应的轮换方式使得二者轮换出来的排列仍然同构。

这个性质极其优美,每当我们做“交换”“轮换”之类字眼的题其实都能这样减少状态数。

假设我们把状态数压缩下来了,那这题其实是可以轻松爆搜 + 矩阵快速幂通过的。

那这个状态数有多少呢?

纯环图的同构其实就是把所有环的大小找出来形成的可重集相等。

直观上来看不会太多,但隐约感觉仍然是阶乘级别?

下面我们来看看这张可爱的表,设状态数为 ddpdf 版里面表格地方不大够,咋调也不行/kk):

11 22 33 44 55 66 77 88 99 1010
11 22 33 55 77 1111 1515 2222 3030 4242
1111 1212 1313 1414 1515 1616 1717 1818 1919 2020
5656 7777 101101 135135 176176 231231 297297 385385 490490 627627
2121 2222 2323 2424 2525 2626 2727 2828 2929 3030
792792 10021002 12551255 15751575 19581958 24362436 30103010 37183718 45654565 56045604
3131 3232 3333 3434 3535 3636 3737 3838 3939 4040
68426842 83498349 1014310143 1231012310 1488314883 1797717977 2163721637 2601526015 3118531185 3733837338
4141 4242 4343 4444 4545 4646 4747 4848 4949 5050
4458344583 5317453174 6326163261 7517575175 8913489134 105558105558 124754124754 147273147273 173525173525 204226204226

真的令人震惊。

感觉状态数远小于 2n2^n,更别提 n!n! 了,在 n16n\le 16 的时候甚至 dnn2d_n\le n^2

而且这是所有置换的有效状态数,有的题可能不是两个数交换而是四五个数,那有可能导致更少的状态。

求出这些状态都是什么只需要爆搜即可,并且需要把一个数组映射到一个数,这里采用 Trie\text{Trie} 实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int GT(int a[]) {
F(i,1,n) vis[i]=0;*c=0;
F(i,1,n) if(!vis[i]) {
int x=i,cnt=0;
do vis[x=a[x]]=1,++cnt;while(x^i);
c[++*c]=cnt;
} sort(c+1,c+*c+1);
int now=0;F(i,1,*c) {
if(!nxt[now][c[i]]) nxt[now][c[i]]=++snt;
now=nxt[now][c[i]];
} if(!id[now]) id[now]=++nid;
return id[now];
}
void dfs() {int id=GT(a);
if(has[id]) return;has[id]=1;
F(i,1,n) F(j,i+1,n) {
swap(a[i],a[j]);
dfs();
swap(a[i],a[j]);
}
}

{a}={b}\{a\}=\{b\} 表示 aabb 图同构。

注意若 {a}={b}\{a\}=\{b\},那么仅能说明 c,d,ac=bd:{c}={d}\forall c,d,ac=bd:\{c\}=\{d\}

并不能说明 {ac}={bc}\{ac\}=\{bc\}

这其实也有一个好处,类似于上题,若我们所求的排列有多个同构排列一起被算进去了,其实是比较难处理的。

那么我们就可以将其事先映射到 eeee 的图是唯一的,没有人与它同构。

换句话说就是所有排列都事先乘上了 b1b^{-1}

Polya 定理

要引入一些群论记号了。

证明不一定严谨,仅作为理解参考。

:由一个集合和一个二元运算组成,二元运算满足封闭性和结合律,存在单位元、逆元,一般用 GG 表示一个群。

子群:若 (G,×)(G,\times) 构成一个群,HG(H,×)H\sube G\wedge(H,\times) 也构成一个群,那么 (H,×)(H,\times) 称为 (G,×)(G,\times) 的子群,记为 (H,×)(G,×)(H,\times)\le(G,\times)

陪集:若 gGg\in G(H,×)(G,×)(H,\times)\le(G,\times),则 {h×ghH}\set{h\times g|h\in H} 称为 HH 的陪集,记作 HgHg

实际上该定义被称为右陪集,左陪集在本文没什么用。

陪集具有如下性质(HG,gGH\le G,g\in G):

  • Hg=H|Hg|=|H|,假设 h1g=h2g=kh_1g=h_2g=k,由于逆元唯一,所以 h1=h2=kg1h_1=h_2=kg^{-1},也就是说不同的元素经过 gg 的变换仍然不同。
  • gHgg\in Hg,由于 eHe\in H,所以 eg=gHgeg=g\in Hg
  • Hg=H    gHHg=H\iff g\in H,右推左根据封闭性以及性质 11 会得到 H|H| 个元素来证明,左推右反证即可。
  • Ha=Hb    ab1HHa=Hb\iff ab^{-1}\in H,两边同时右乘 b1b^{-1} 变为性质 33
  • HaHbHa=HbHa\cap Hb\ne \varnothing\Rightarrow Ha=Hb,即陪集之间要么不交要么相等,证明:

首先若 gH,hHg\notin H,h\in H,则 hgHhg\notin H,假设 hgHhg\in Hh1hg=gHh^{-1}hg=g\in H,矛盾。

所以若 gHg\notin H,则 HgHgHH 无交,gHg\in H 是性质 33

  • 全体陪集的并为 GG,证明考虑 gHgg\in Hg,所以每个元素都至少在一个陪集中出现,事实上在且仅在一个陪集中出现,因为性质 55

HGH\le G G/HG/HGGHH 的右陪集构成的集合 {HggG}\set{Hg|g\in G}

洛谷第一篇题解中该记号指左陪集,本文为了叙述的统一性定义其为右陪集。

HGH\le G [G:H][G:H]G/H|G/H|

(怎么感觉后者还简洁了些,不过前者是公认的记号。)

Lagrange\rm Lagrange 定理H[G:H]=G|H|[G:H]=|G|,证明方法就是所有陪集大小相同且无交且并起来为 GG

群作用:对于群 GG 和集合 MM,定义群作用为满足如下条件的二元函数 φ(m,g)\varphi(m,g),以下记 mφgm*_{\varphi}gφ(m,g)\varphi(m,g)

  • gG,mMg\in G,m\in M
  • mφe=mm*_{\varphi}e=m
  • mφaφb=mφ(a×b)m*_{\varphi}a*_{\varphi}b=m*_\varphi(a\times b)

GG 作用于集合 MM,值得注意的是这里的集合 MM 要求所有 mφgMm*_\varphi g\in M,即 φ*_{\varphi} 一个 GG 中的元素这个操作对 MM 是封闭的。

轨道:若 GG 作用于集合 XX,则 xXx\in X 的轨道 G(x)G(x) 定义为 xx 通过 GG 能转移到的元素集合,即 {xφggG}\set{x*_\varphi g|g\in G},可以理解为 GGxxG(x)G(x) 这么多作用效果。

无需在意是一步转移还是两步转移,因为根据群的性质后者可以压缩成前者。

稳定子xx 的稳定子 Gx={gxφg=x}G^x=\set{g|x*_{\varphi}g=x},即(作用于 xx 不改变 xx)的 GG 元素的个数。

轨道 - 稳定子定理G(x)Gx=G|G(x)||G^x|=|G|

证明:

首先可以证明 GxGG^x\le G,只需验证封闭性、逆元、单位元即可。

接下来只需证 G(x)=[G:Gx]|G(x)|=[G:G^x]

xφf=xφgx*_\varphi f=x*_\varphi g,则 xφ(f×g1)=xx*_\varphi(f\times g^{-1})=x,所以 f×g1Gxf\times g^{-1}\in G^x,根据陪集性质我们得到 Gxf=GxgG^xf=G^xg

这告诉我们作用效果相同意味着在同一陪集中,上述过程也可以逆过来告诉我们这是充要的,由于 GxG^x 的陪集数量为 GGx\frac{|G|}{|G^x|},可得总共有这么多种作用效果,作用效果数也就是 G(x)|G(x)|

等价类:若 GG 作用于 XXx,yX,fGx,y\in X,\exist f\in G 满足 xφf=yx*_\varphi f=y,那么定义 x,yx,y 属于同一个等价类,不难看出 G(x)G(x) 是一个无法扩展的等价类(极大等价类),所以等价类的概念其实就是轨道。

不动点Xg={xxφg=x}X^g=\set{x|x*_\varphi g=x},注意与稳定子区分开,不动点是 xx 的数量。

Burnside\rm Burnside 引理:记 XXGG 作用下不同的等价类集合为 X/G={xφgxX,gG}X/G=\set{x*_\varphi g|x\in X,g\in G},则:

X/G=1GgGXg|X/G|=\frac{1}{|G|}\sum_{g\in G}|X^g|

用文字描述就是每个元素 gg 作用于 XX 的不动点个数的算术平均值。

证明:

X/G=xX1G(x)=xX1GGx=xXGxG=1GxXGx=1GgGXg\begin{aligned}|X/G|&=\sum_{x\in X}\frac{1}{G(x)}\\&=\sum_{x\in X}\frac{1}{\frac{|G|}{|G^x|}}\\&=\sum_{x\in X}\frac{|G^x|}{|G|}\\&=\frac{1}{|G|}\sum_{x\in X}|G^x|\\&=\frac1{|G|}\sum_{g\in G}|X^g|\end{aligned}

后面几步应该都能看懂,第一步是考虑每个等价类会被统计 G(x)G(x) 次。

那这个东西有什么用呢,其最大的用处就是把对 xx 的枚举变为对 gg 的枚举。

我们进一步可以得到 Poˊlya\rm Pólya 定理mm 个元素对 nn 个对象染色,额外给定置换群 GG,若 gG,x=yφgg\in G,x=y*_\varphi gx,yx,y 两种方案认为是相同的,则不同的染色方案为:

1GpGmC(p)\frac{1}{|G|}\sum_{p\in G}m^{C(p)}

其中 C(p)C(p) 表示 pp 这个置换的构成中有多少个环。

理解起来很方便,每个环的颜色必须相同嘛。

P4980 【模板】Polya 定理

TT 组数据,每次给定一个 nn,求大小为 nn 的环,nn 种颜色,给每个点染色,问有多少种不同的染色方案,不同定义为不存在一种旋转方式使得两个环完全相同。

T103,n109T\le10^3,n\le 10^9

可以将集合 XX 的视为所有的 nnn^n 个对序列的染色方案,将 GG 视为旋转。

显然 G=n|G|=n,你可以有 nn 种旋转方案。

我们枚举这 nn 种旋转方案,考虑旋转 ii 个单位会产生多少个不动点原序列。

考虑每个元素 jj(j+i)modn(j+i)\bmod n 连一条边,这会产生 gcd(i,n)\gcd(i,n) 个子环,每个子环的颜色必须相同,环与环之间无所谓,于是:

ans=1ni=1nngcd(i,n)=1nknnkd=1n/k[(d,n/k)=1]=1nknnkφ(n/k)\begin{aligned}{\rm ans}&=\frac 1 n\sum_{i=1}^nn^{\gcd(i,n)}\\&=\frac 1 n\sum_{k\mid n}n^k\sum_{d=1}^{n/k}[(d,n/k)=1]\\&=\frac 1 n\sum_{k\mid n}n^k\varphi(n/k)\end{aligned}

式子化的熟练了我们其实可以知道 i=1nf(gcd(n,i))=inf(i)φ(n/i)\sum_{i=1}^nf(\gcd(n,i))=\sum_{i|n}f(i)\varphi(n/i)

暴力根号求 φ\varphi 即可,但精细实现的话可以做到 O(d(n)+p(n))\cal O(d(n)+p(n)) 完成该过程,其中 dd 为约数个数,pp 为质因数分解复杂度,方法是搜因数的质因数分解的同时求出 φ\varphi

P3307 [SDOI2013] 项链

TT 组数据,每次给定 n,an,a,定义环上每个元素为 (x,y,z)(x,y,z[1,a],gcd(x,y,z)=1)(x,y,z)(x,y,z\in[1,a],\gcd(x,y,z)=1) 这样的 无序三元组,要求对 nn 个元素的环计数,要求相邻两个元素不能相同。

T10,n1014,a107T\le10,n\le10^{14},a\le 10^7

首先我们先求出每个元素有多少种取值方案,可以讨论用了几种颜色,设其为 dd

首先是后面会用到的一些函数:

S1(x)=x(x+1)2S2(x)=x(x+1)(2x+1)6\begin{aligned}&{\rm S}_1(x)=\frac{x(x+1)}{2}\\&{\rm S}_2(x)=\frac{x(x+1)(2x+1)}6\end{aligned}

一种颜色:11

两种颜色(式子中的 nnaa):

2i=1nj=1i1[(i,j)=1]= 2d=1nμ(d)i=1n/dj=1i11= 2d=1nμ(d)Sf(n/d1),f(x)=xSf(x)=S1(x)\begin{aligned}&2\sum_{i=1}^n\sum_{j=1}^{i-1}[(i,j)=1]\\=\ &2\sum_{d=1}^n\mu(d)\sum_{i=1}^{n/d}\sum_{j=1}^{i-1}1\\=\ &2\sum_{d=1}^n\mu(d){\rm S}f(n/d-1),f(x)=x\\&{\rm S}f(x)={\rm S}_1(x)\end{aligned}

三种颜色(式子中的 nnaa):

i=1nj=1i1k=1j1[(i,j,k)=1]= d=1nμ(d)i=1n/dj=1i1j=1j11= d=1nμ(d)i=1n/dS1(i2)= d=1nμ(d)i=1n/d(i2)(i1)2= d=1nμ(d)f(n/d),f(x)=S2(x)3S1(x)+2x2\begin{aligned}&\sum_{i=1}^n\sum_{j=1}^{i-1}\sum_{k=1}^{j-1}[(i,j,k)=1]\\=\ &\sum_{d=1}^n\mu(d)\sum_{i=1}^{n/d}\sum_{j=1}^{i-1}\sum_{j=1}^{j-1}1\\=\ &\sum_{d=1}^n\mu(d)\sum_{i=1}^{n/d}{\rm S}_1(i-2)\\=\ &\sum_{d=1}^n\mu(d)\sum_{i=1}^{n/d}\frac{(i-2)(i-1)}{2}\\=\ &\sum_{d=1}^n\mu(d)f(n/d),f(x)=\frac{{\rm S}_2(x)-3{\rm S}_1(x)+2x}2\end{aligned}


接下来我们要解决这样一个问题:每个元素有 dd 种情况,相邻元素必须不同,对环计数。

首先还是连边变成 gcd(i,n)\gcd(i,n) 个环,每个环的颜色必须相等,然后就转化成对满足长度为 gcd(i,n)\gcd(i,n) 且相邻元素(包括首和尾)不同的 序列 计数。

对这种序列计数我们设 fif_i 是长为 ii 的序列,每次可以把第一个元素抠掉,若两边颜色相同就把三个缩成一个,被缩掉的中间元素有 d1d-1 种选择,否则就仅仅把中间的给缩掉,并有 d2d-2 种选择。

f1=d,f2=d(d1),fi=(d1)fi2+(d2)fi1f_1=d,f_2=d(d-1),f_i=(d-1)f_{i-2}+(d-2)f_{i-1}

约数估算一下 nn 大概有 n1/3n^{1/3} 个约数,所以 ff 使用矩阵快速幂解决足够。

需要注意一个小细节,gcd(i,n)1\gcd(i,n)\ne 1,否则每个点就会被要求跟相邻元素的颜色相同。

ans1ni=1n[gcd(i,n)1]f(gcd(i,n))=1nin,i1f(i)φ(n/i){\rm ans}\gets \frac 1 n\sum_{i=1}^n[\gcd(i,n)\ne 1]f(\gcd(i,n))=\frac 1 n\sum_{i|n,i\ne 1}f(i)\varphi(n/i)

带权 Burnside/生成函数形式

有空了补,目前没见到应用。

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
总字数 231.7k 访客数 访问量