- admin 的博客
群论小记
- @ 2026-7-10 10:05:18
群论小记 更新于 2026/7/9 19:53:10 作者
command_block
1.群的概念与基本性质
给定一个集合 ,和其上的二元运算 , 满足如下性质:
-
封闭性 : 若 ,则必有 。
-
结合律 : 对于任意的 ,有
-
存在单位元 : 存在一个 ,使得对于任意的 ,满足 。
元素 则被称作单位元。
-
存在逆元 : 对于任意的 ,存在一个 ,满足 。
元素 可以记作 。
则称 在 运算下是一个群。
有时把 省略不写。
- 群的单位元唯一。
设有两个不同的单位元 ,根据单位元的定义能得到 ,矛盾。
证左部,右部同理。
$ab=ac\ \Rightarrow\ a^{-1}(ab)=a^{-1}(ac)\ \Rightarrow\ (a^{-1}a)b=(a^{-1}a)c\ \Rightarrow\ b=c$
- 每个元素的逆唯一。
若 有两个不同的逆 。
则有 ,使用 约去 得到 。
若只希望了解置换计数,可以到此为止。
-
对于任意的(有限)群
对于任意的 都存在一个常数 ,使得 。此时称 为 的阶。
且有 。
任取 ,构造 。
由于封闭性,这 个元素都属于 ,但 ,所以必有两者相等。
不妨设 。约掉 则有 。
令 ,则有 。 能得到
2. 置换与置换群
- 置换的定义
假设有 这 个元素, 令 被元素 所取代。
满足各个 互不相同,也就是“移动”后, 个元素仍然都存在。
写作置换 : $\begin{pmatrix}1&2&3&...&n\\a_1&a_2&a_3&...&a_n\end{pmatrix}$
如
这个置换就代表着:
- 把 移到第 个
- 把 移到第 个
- 把 移到第 个
- 把 移到第 个
又作:
$1\xrightarrow{p}3,\quad 2\xrightarrow{p}1,\quad 3\xrightarrow{p}4,\quad 4\xrightarrow{p}2$
- 置换乘法
置换的乘法就是把映射叠加。
设
则 $1\xrightarrow{p}3\xrightarrow{p_2}4,\quad 2\xrightarrow{p}1\xrightarrow{p_2}2,\quad 3\xrightarrow{p}4\xrightarrow{p_2}3,\quad 4\xrightarrow{p}2\xrightarrow{p_2}1$
所以有
也可以这样写 :
$\small\begin{pmatrix}1&2&3&4\\3&1&4&2\\\end{pmatrix}*\begin{pmatrix}1&2&3&4\\2&1&4&3\end{pmatrix}=\begin{pmatrix}1&2&3&4\\3&1&4&2\end{pmatrix}*\begin{pmatrix}3&1&4&2\\4&2&3&1\end{pmatrix}=\begin{pmatrix}1&2&3&4\\4&2&3&1\end{pmatrix}$
容易证明如下的几条基本性质 :
-
置换的乘积还是置换。
-
置换乘法满足结合律。
-
单位元为 $\begin{pmatrix}1&2&3&...&n\\1&2&3&...&n\\\end{pmatrix}$
-
$\begin{pmatrix}1&2&...&n\\a_1&a_2&...&a_n\end{pmatrix}$ 的逆为 $\begin{pmatrix}a_1&a_2&...&a_n\\1&2&...&n\end{pmatrix}$
但注意,置换乘法一般不满足交换律。
- 置换群
根据上面的若干性质,不难证明对 作用的所有置换形成一个群。
总是研究全体置换,未免乏味,我们一般只研究一个子群。
有如下事实 : 对于任意一个 阶有限群,存在一个 阶置换群与其同构。
解释一下同构是什么意思,想想一个二分图,左侧的点用对子 描述,向右侧的 连边。
若这两个图同构,则称两个群同构。(其实就是把所有的运算结果打了个表)
现在我们就是要证明置换群能够造出任意的图来。
对于 ,取 ,写出 。
这些乘积必然两两不同。假设有 ,约去 可得 ,矛盾。
我们设 $p_k=\begin{pmatrix}a_1&a_2&...&a_n\\a_1a_k&a_2a_k&...&a_na_k\end{pmatrix}$ (其实就是把所有关于 的运算写出来)
令 和 相对应,写作 。
则有 ,证明如下 :
$p_ip_j=\begin{pmatrix}a_1&a_2&...&a_n\\a_1a_i&a_2a_i&...&a_na_i\end{pmatrix}\begin{pmatrix}a_1&a_2&...&a_n\\a_1a_j&a_2a_j&...&a_na_j\end{pmatrix}$
$=\begin{pmatrix}a_1&a_2&...&a_n\\a_1a_i&a_2a_i&...&a_na_i\end{pmatrix}\begin{pmatrix}a_1a_i&a_2a_i&...&a_na_i\\(a_1a_i)a_j&(a_2a_i)a_j&...&(a_na_i)a_j\end{pmatrix}$
$=\begin{pmatrix}a_1&a_2&...&a_n\\a_1(a_ia_j)&a_2(a_ia_j)&...&a_n(a_ia_j)\end{pmatrix}$
注意到,前面的“二分图”有 个 的信息,而 阶置换群也有 个信息,所以本质上其实是暴力打表。
- 置换的循环
把置换看做一张有向图, 连边 。不难发现,每个点只有一个出度一个入度,所以会形成若干个环。
的循环是
的循环是
的循环是 ,通常省略一元循环写作 。
置换可以用这些环来表示,而且表示方法是唯一的。
由于比双层写法更简洁,下面有时会以循环的方式写出置换。
2. Burnside / Polya
设 是 的一个置换群。
- 不动点
对于 ,若 ,则称 是 下的不动点。
将 下的不动点个数即为 。
- 不动置换类
对于 ,若 是 的不动点,则称 属于 不动置换类。
记作 。能够发现, 是 的一个子群。
- 等价类
等价类 设为 对元素 施加任意的 中置换,能够获得的元素集合。 (又称为轨迹)
如 。
那么 在置换的作用下可以到达 ,但不可能到达 ,则有 。
当 属于一个等价类时,有
构造 之间的双射。
根据等价类的定义,存在置换 使得 。
对于任意的 ,有 $y\xrightarrow{t^{-1}} x\xrightarrow{p} x\xrightarrow{t}y$ ,构造 ,则必有 。
这就是一组从 到 的映射,同理也有 到 的映射。
构建了双射之后,元素个数显然是相同的。
-
轨道-稳定化子定理
设 ,设
根据等价类的定义,对于每个 都存在 使得 。
设置换集合 ,显然有 。
由于 ,则有
能够发现 时 ,。(这是显然的,因为两个群对 的作用不同)
那么有 。
另一方面,对于任意的 ,由等价类的定义,必有 使得 。
那么有 $k\xrightarrow{p}a_i\xrightarrow{p_i^{-1}}k \Longrightarrow p*p_i^{-1}\in Z_k \Longrightarrow p\in Z_kp_i$
所以, 中的每个置换都被包含在某个 中,则有 。
综上可得
$|G|=|Z_kp_1|+|Z_kp_2|+...+|Z_kp_m|=m|Z_k|=|E_k||Z_k|$ ,证毕。
-
Burnside引理
称 中本质不同的个数,为等价类个数,设为 ,则有
人话 : 等价类个数=各个置换下不动点个数的和的平均数。
设 。
记 。
能够发现, (对置换 ,枚举各个元素,查看是否不动)
同时也有 (对元素 ,枚举各个置换,查看是否不动)
则所有 的和 $=\sum\limits_{i=1}^m\sum\limits_{k=1}^ns_{i,k}=\sum\limits_{i=1}^mc(a_i)=\sum\limits_{k=1}^n|Z_k|$。
不妨设 个互不相同的等价类为 ,则有 。
那么,由于 是 的一个划分,我们可以把 换成
则有 $\sum\limits_{k=1}^n|Z_k|=\sum\limits_{t=1}^l\sum\limits_{i\in E_t}|Z_i|$
回忆 ,由于 同属于一个等价类,可以把 换成 。
$\sum\limits_{t=1}^l\sum\limits_{i\in E_t}|Z_t|=\sum\limits_{t=1}^l|E_t||Z_t|$
又因为 ,所以有上式
于是就有 ,证毕。
- Polya定理
以问题引入 : 给出一条长度为 的链条,每一节可以染上 种不同的颜色,但是翻转之后相同的方案被视为本质相同,问不同的染色方案数。
若将每种染色方案视为一个元素,令 为这些元素的集合,那么 在“翻转置换”作用下的等价类个数即为答案。
问题在于,置换的大小是 ,非常庞大,不便于计算。
能够发现,“翻转”同样是对 这些“位置”的置换,且也是群。
若能把对“位置”的小置换群,和对“状态”的大置换群联系起来,就能更方便地计算了。
-
设有 个元素,每个元素有 种染色方法。
设 是 个元素的置换群,则染色总方案数为 :
其中 指在置换 下,不动的染色方案数。
-
比如 。
那么染成 ,置换完了之后还是 ,则称之为不动的染色方案
染成 置换完了之后是 ,和原来不相等,则不是“不动方案”。
-
-
设 是对状态的置换群。不难发现大置换和小置换有对应关系,使用小置换对每种状态讨论即可得到大置换。
形式化的讲,设 对应 。
若一种染色方案 在经过 的“移动”之后,变为了 ,则 。
所以有 。
根据经典的Burnside引理,可以得到答案为
而 的意义正是 中相对应的置换 下不动的染色方案数,证毕。
-
接下来介绍如何求 。
设 为 的循环个数,则(根据等式的传递性)每个循环中必须染上同一种颜色,且不同循环之间没有影响。
能得到 。
回到题目, 中有两个置换 : $e,\begin{pmatrix}1&2&3&4&5&6\\6&5&4&3&2&1\end{pmatrix}$。
后者有循环节 ,则贡献为
前者有循环节 ,则贡献为
总方案数是 。
3. 习题
这道题里的置换就是旋转。
有旋转 格的置换,共 个。
设 $p_i=\begin{pmatrix}1&2&...&n-i&n-i+1&...&n\\1+i&2+i&...&n&1&...&i\\\end{pmatrix}$ (旋转 格)
Polya式子 :
暴力 : 根据上文介绍的方法,对每个置换缩点求循环个数 ,复杂度 。
打表或者拿出草稿纸画了一通后,你会发现 。
-
首先注意到 循环节大小为 。
若每次跳 步,在长度为 的环上,多少次才能回到原点呢?
当 时,可以证明 在 意义下互不相同。
此时的答案就是 。
若 ,采用模分类,设 ,若从 开始,不难发现 的位置都是无用的。
这就变成了子问题 ,此时两者互质,答案就是 。
得 ${\rm Ans}=\dfrac{1}{n}\sum\limits_{i=1}^nn^{gcd(n,i)}$
相信已近在学习群论的你,一定能把这道数论水题秒掉的。
$=\dfrac{1}{n}\sum\limits_{d|n}k^d\sum\limits_{i=1}^n[\gcd(n,i)=d]$
-
后面的
整理得
大力求欧拉函数大概是的样子(反正快速幂也是这个复杂度)。
然而还有一个质因数分解+dfs凑出所有因数+光速幂的 解法,懒得写。
Code:
#include<algorithm>
#include<cstdio>
#define ll long long
using namespace std;
const int mod=1000000007;
ll powM(ll a,int t){
ll ret=1;
while(t){
if (t&1)ret=ret*a%mod;
a=a*a%mod;t>>=1;
}return ret;
}
int phi(int n)
{
int ans=n;
for (int i=2;i*i<=n;i++)
if (n%i==0){
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
if (n>1)ans=ans/n*(n-1);
return ans;
}
void solve(int n)
{
ll ans=0;
for (int i=1;i*i<=n;i++)
if (n%i==0){
if (i*i!=n)ans=(ans+powM(n,n/i-1)*phi(i))%mod;
ans=(ans+powM(n,i-1)*phi(n/i))%mod;
}
printf("%lld\n",ans);
}
int T,n;
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d",&n);
solve(n);
}return 0;
}
第一眼这道题以为是子集或者容斥什么的,结果数据范围 ? 怕不是有多项式算法?
今早闲得无聊拿着《组合数学(第4版)》看了看,里面居然有讲到这个问题。
边 (有,无) 的状态可以看做对一个完全图染色,某条边染成黑色说明存在,染成白色就假装不存在,我们成功地把这个问题转化成了一个染色计数问题。
我们先看看式子 :
我们现在是在对边计数,但是我们的置换是所有的点置换。
显然,可以由点置换构造出边置换,但是点置换的个数是 的,无法直接枚举。我们需要找到更好的性质来批量处理。
万幸的是, 点置换循环节的构成 和 边置换的不动点个数 有一定的关系。
考虑一个点置换,他每个循环的大小为 (为循环节个数,且 )
能够感知,所有循环节组成相同的点置换,边的等价类个数是相同的。
也就是说我们只要枚举 ,也就是 的正整数拆分,就能确定一类边置换。
而正整数拆分的数量级是 ,是亚指数的。本题中极限情况仅在百万级。
现在,对于一组 ,计算出这个完全图会究竟会被分成多少个等价类,设其为 ,根据 那么不动点个数就是 。
- 对于循环节内的边,会被分为个等价类。
理解 : 我们可以把这个循环节看成一个圈,由于这个圈会转,肯定会让某些边相同。
循环内节点按 编号,假设有边 ,那么边 , ……和 肯定都和 相同。
我们枚举p,会发现 的情况会和 的情况重复。

如图 : 左边 ,等价类数为 ; 右边 ,等价类数为 。
-
对于两个循环节之间的边,会被分为个等价类。
理解 : 我们还是采用圈来理解,由于这个两个圈都会转,情况有点复杂。
循环内节点按 与 编号,假设有边 ,那么有多少条边和这条边相同呢?
这等价于考虑 : 这条边会在多少次置换后回到原位 ?
答案是 ,如果不理解的话,想象着两个齿轮咬合着转。
那么每个等价类的边得个数为 ,边的总数为 ,则等价类的总数是

如图 : 左边 ,等价类数为 ;
第一个等价类的边
第二个等价类的边
那么根据上述,对于循环节大小为 的点置换,其对应的边置换的贡献为:
$$\large{2^{\small\sum\limits_{i=1}^m\lfloor\frac{S_i}{2}\rfloor+\sum\limits_{i=1}^m\sum\limits_{j=i+1}^mgcd(S_i,S_j)}}$$我们接下来还要算循环节大小为 的点置换有几个。
我们考虑把 分成 个集合,大小分别为 。
我们考虑生成一个长为 的排列,然后按照 分成 组,其实就是多重排列问题。
得
如果有两个 相同,是可以调换顺序的,所以还要除掉一些东西。
设 为 的个数,得
我们还要在每个集合内连边,使得它构成一个循环。
元有标号环的个数显然是 。
可以视作把 元链首尾相,由于旋转,每个换对应 个链,方案数即为 。
乘回划分集合的方案数,得到$\dfrac{n!*\Pi_{i=1}^m(S_i-1)!}{\Pi_{i=1}^mS_i!*\Pi_{i=1}^nB_i!}=\dfrac{n!}{\Pi_{i=1}^mS_i*\Pi_{i=1}^nB_i!}$
然后在乘上对应的边置换的贡献,得到
$$\dfrac{n!}{\Pi_{i=1}^mS_i*\Pi_{i=1}^nB_i!}*\large{2^{\small\sum\limits_{i=1}^m\lfloor\frac{S_i}{2}\rfloor+\sum\limits_{i=1}^m\sum\limits_{j=i+1}^mgcd(S_i,S_j)}}$$别忘了除以置换个数 。
最后注意实现复杂度和常数,小心被卡。
Code:
#include<cstdio>
using namespace std;
const int mod=997;
int n;
int powM(int a,int t=mod-2){
int ret=1;
while(t){
if (t&1)ret=ret*a%mod;
a=a*a%mod;t>>=1;
}return ret;
}
int facn,inv[66],ifac[66],gcd[66][66],
s[66],b[66],ans;
void dfs(int num,int pos,int last)
{
if (num==0){
int t=0,sav=facn;
for (int i=1;i<=n;i++)b[i]=0;
for (int i=1;i<pos;i++)b[s[i]]++;
for (int i=1;i<=n;i++)sav=sav*ifac[b[i]]%mod;
for (int i=1;i<pos;i++)sav=sav*inv[s[i]]%mod;
for (int i=1;i<pos;i++)
for (int j=i+1;j<pos;j++)
t+=gcd[s[i]][s[j]];
for (int i=1;i<=n;i++)t+=s[i]/2;
sav=sav*powM(2,t)%mod;
ans=(ans+sav)%mod;
return ;
}if (last>num)last=num;
for (int i=1;i<=last;i++){
s[pos]=i;
dfs(num-i,pos+1,i);
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)inv[i]=powM(i);
ifac[0]=1;
for (int i=1;i<=n;i++)
ifac[i]=ifac[i-1]*inv[i]%mod;
facn=powM(ifac[n]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
if (i%k==0&&j%k==0)gcd[i][j]=k;
dfs(n,1,n);
printf("%d",ans*ifac[n]%mod);
return 0;
}
类似的题目 : P4128 [SHOI2006]有色图