群论小记 更新于 2026/7/9 19:53:10 作者

command_block

1.群的概念与基本性质

定义:\color{blue}\text{定义}: 给定一个集合 GG ,和其上的二元运算 * , 满足如下性质:

  • 封闭性 : 若 a,bGa,b\in G ,则必有 (ab)G(a*b)\in G

  • 结合律 : 对于任意的 a,b,cGa,b,c\in G ,有 (ab)c=a(bc)(a*b)*c=a*(b*c)

  • 存在单位元 : 存在一个 eGe\in G ,使得对于任意的 aGa\in G ,满足 ae=ea=aa*e=e*a=a

    元素 ee 则被称作单位元。

  • 存在逆元 : 对于任意的 aGa\in G ,存在一个 bGb\in G ,满足 ab=ba=ea*b=b*a=e

    元素 bb 可以记作 a1a^{-1}

则称 GG* 运算下是一个

有时把 * 省略不写。

  • 定理 1.1:\color{blue}\text{定理 1.1}: 群的单位元唯一。

设有两个不同的单位元 e1,e2e_1,e_2 ,根据单位元的定义能得到 e1=e1e2=e2e_1=e_1e_2=e_2 ,矛盾。

  • 定理 1.2:\color{blue}\text{定理 1.2}: ab=acb=c, ba=cab=cab=ac\Rightarrow b=c,\ ba=ca\Rightarrow b=c

证左部,右部同理。

$ab=ac\ \Rightarrow\ a^{-1}(ab)=a^{-1}(ac)\ \Rightarrow\ (a^{-1}a)b=(a^{-1}a)c\ \Rightarrow\ b=c$

  • 定理 1.3:\color{blue}\text{定理 1.3}: 每个元素的逆唯一。

aa 有两个不同的逆 b,cb,c

则有 ab=e=acab=e=ac ,使用定理1.2\color{blue}\text{定理1.2} 约去 aa 得到 b=cb=c

若只希望了解置换计数,可以到此为止。


  • 定理 1.4:\color{blue}\text{定理 1.4}: 对于任意的(有限)群 G={e,a1,a2...an}G=\{e,a_1,a_2...a_n\}

    对于任意的 aGa\in G 都存在一个常数 ord(a){\rm ord}(a) ,使得 aord(a)=ea^{{\rm ord}(a)}=e。此时称 ord(a){\rm ord}(a)aa 的阶。

    且有 a1=aord(a)1a^{-1}=a^{{\rm ord}(a)-1}

任取 aGa\in G ,构造 {a,a2,a3...an,an+1}\{a,a^2,a^3...a^n,a^{n+1}\}

由于封闭性,这 n+1n+1 个元素都属于 GG ,但 G=n|G|=n ,所以必有两者相等。

不妨设 ax=ay,x<ya^x=a^y,x<y。约掉 axa^x 则有 ayx=ea^{y-x}=e

ord(a)=yx{\rm ord}(a)=y-x ,则有 ar(a)1a=ar(a)=ea^{r(a)-1}a=a^{r(a)}=e。 能得到 ar(a)1=a1a^{r(a)-1}=a^{-1}

2. 置换与置换群

  • 置换的定义

假设有 1,2,3...n1,2,3...nnn 个元素, 令 kk 被元素 aka_k 所取代。

满足各个 aka_k 互不相同,也就是“移动”后, nn 个元素仍然都存在。

写作置换 : $\begin{pmatrix}1&2&3&...&n\\a_1&a_2&a_3&...&a_n\end{pmatrix}$

p=(12343142)p=\begin{pmatrix}1&2&3&4\\3&1&4&2\end{pmatrix}

这个置换就代表着:

  • 11 移到第 33
  • 22 移到第 11
  • 33 移到第 44
  • 44 移到第 22

又作:

$1\xrightarrow{p}3,\quad 2\xrightarrow{p}1,\quad 3\xrightarrow{p}4,\quad 4\xrightarrow{p}2$

  • 置换乘法

置换的乘法就是把映射叠加。

p2=(12342143)p_2=\begin{pmatrix}1&2&3&4\\2&1&4&3\end{pmatrix}

则 $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$

所以有 pp2=(12344231)p*p_2=\begin{pmatrix}1&2&3&4\\4&2&3&1\end{pmatrix}

也可以这样写 :

$\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}$

但注意,置换乘法一般不满足交换律。

  • 置换群

根据上面的若干性质,不难证明对 1...n1...n 作用的所有置换形成一个群。

总是研究全体置换,未免乏味,我们一般只研究一个子群。

有如下事实 : 对于任意一个 nn 阶有限群,存在一个 nn 阶置换群与其同构。

解释一下同构是什么意思,想想一个二分图,左侧的点用对子 (a,b)(a,b) 描述,向右侧的 aba*b 连边。

若这两个图同构,则称两个群同构。(其实就是把所有的运算结果打了个表)

现在我们就是要证明置换群能够造出任意的图来。

对于 G={a1,a2...an}G=\{a_1,a_2...a_n\} ,取 aka_k ,写出 aka1,aka2...akana_ka_1,a_ka_2...a_ka_n

这些乘积必然两两不同。假设有 akai=akaja_ka_i=a_ka_j ,约去 aka_k 可得 ai=aja_i=a_j ,矛盾。

我们设 $p_k=\begin{pmatrix}a_1&a_2&...&a_n\\a_1a_k&a_2a_k&...&a_na_k\end{pmatrix}$ (其实就是把所有关于 aka_k 的运算写出来)

aka_kpkp_k 相对应,写作 akpka_k\leftrightarrow p_k

则有 aiajpipja_ia_j\leftrightarrow p_ip_j ,证明如下 :

$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}$

注意到,前面的“二分图”有 n2n^21...n 1...n 的信息,而 nn 阶置换群也有 n2n^2 个信息,所以本质上其实是暴力打表。

  • 置换的循环

把置换看做一张有向图, 连边 iaii\rightarrow a_i 。不难发现,每个点只有一个出度一个入度,所以会形成若干个环。

(12343142)\begin{pmatrix}1&2&3&4\\3&1&4&2\\\end{pmatrix} 的循环是 (1,2,3,4)(1,2,3,4)

(12342143)\begin{pmatrix}1&2&3&4\\2&1&4&3\\\end{pmatrix} 的循环是 (1,2)(3,4)(1,2)(3,4)

(12342134)\begin{pmatrix}1&2&3&4\\2&1&3&4\\\end{pmatrix} 的循环是 (1,2)(3)(4)(1,2)(3)(4) ,通常省略一元循环写作 (1,2)(1,2)

置换可以用这些环来表示,而且表示方法是唯一的。

由于比双层写法更简洁,下面有时会以循环的方式写出置换。

2. Burnside / Polya

GG1...n1...n 的一个置换群。

  • 不动点

对于 pGp\in G,若 kpkk\xrightarrow{p}k ,则称 kkpp 下的不动点。

pp 下的不动点个数即为 c(p)c(p)

  • k\bf k 不动置换类

对于 pGp\in G ,若 kkpp 的不动点,则称 pp 属于 kk 不动置换类。

记作 pZkp\in Z_k。能够发现, ZkZ_kGG 的一个子群。

  • 等价类

等价类 EkE_k 设为 对元素 kk 施加任意的 GG 中置换,能够获得的元素集合。 (又称为轨迹)

G={e,(1,2),(3,4),(1,2)(3,4)}G=\{e,(1,2),(3,4),(1,2)(3,4)\}

那么 11 在置换的作用下可以到达 1,21,2 ,但不可能到达 3,43,4 ,则有 E1={1,2}E_1=\{1,2\}

定理 2.1:\color{blue}\text{定理 2.1}:x,yx,y 属于一个等价类时,有 Zx=Zy|Z_x|=|Z_y|

证明:\color{blue}\text{证明}: 构造 Zx,ZyZ_x,Z_y 之间的双射。

根据等价类的定义,存在置换 tGt\in G 使得  xty,yt1x\ x\xrightarrow{t} y,\quad y\xrightarrow{t^{-1}} x

对于任意的 pZxp\in Z_x ,有 $y\xrightarrow{t^{-1}} x\xrightarrow{p} x\xrightarrow{t}y$ ,构造 p=t1ptp'=t^{-1}pt ,则必有 pZyp'\in Z_y

这就是一组从 ZxZ_xZyZ_y 的映射,同理也有 ZyZ_yZxZ_x 的映射。

构建了双射之后,元素个数显然是相同的。

  • 轨道-稳定化子定理

    定理 2.2:\color{blue}\text{定理 2.2}: Zk×Ek=G|Z_k|\times|E_k|=|G|

证明:\color{blue}\text{证明}:m=Ekm=|E_k| ,设 Ek={a1(=k),a2...am}E_k=\{a_1(=k),a_2...a_m\}

根据等价类的定义,对于每个 aia_i 都存在 piGp_i\in G 使得 kpiaik\xrightarrow{p_i} a_i

设置换集合 Gi=ZkpiG_i=Z_kp_i ,显然有 GiGG_i\subseteq G

由于 kpZkkpiaik\xrightarrow{p\in Z_k}k\xrightarrow{p_ i}a_i ,则有 kpZkpiaik\xrightarrow{p\in Z_kp_i}a_i

能够发现 iji≠j 时 ,GiGj=G_i∩G_j=\varnothing。(这是显然的,因为两个群对 kk 的作用不同)

那么有 G1+G2+...GmGG_1+G_2+...G_m\subseteq G

另一方面,对于任意的 pGp\in G ,由等价类的定义,必有 aia_i 使得 kpaik\xrightarrow{p}a_i

那么有 $k\xrightarrow{p}a_i\xrightarrow{p_i^{-1}}k \Longrightarrow p*p_i^{-1}\in Z_k \Longrightarrow p\in Z_kp_i$

所以, GG 中的每个置换都被包含在某个 GiG_i 中,则有 GG1+G2+...+GmG\subseteq G_1+G_2+...+G_m

综上可得 G=G1+G2+...+Gm=Zkp1+Zkp2+...+ZkpmG=G_1+G_2+...+G_m=Z_kp_1+Z_kp_2+...+Z_kp_m

$|G|=|Z_kp_1|+|Z_kp_2|+...+|Z_kp_m|=m|Z_k|=|E_k||Z_k|$ ,证毕。

  • Burnside引理

    定理 2.3:\color{blue}\text{定理 2.3}:E1...nE_{1...n} 中本质不同的个数,为等价类个数,设为 ll ,则有

    l=1GpGc(p)l=\dfrac{1}{|G|}\sum\limits_{p\in G}c(p)

    人话 : 等价类个数=各个置换下不动点个数的和的平均数。

证明:\color{blue}\text{证明}:m=G,G={a1,a2...am}m=|G|,G=\{a_1,a_2...a_m\}

si,k=[kaik]s_{i,k}=[k\xrightarrow{a_i}k]

能够发现, k=1nsi,k=c(ai)\sum\limits_{k=1}^ns_{i,k}=c(a_i) (对置换 aia_i ,枚举各个元素,查看是否不动)

同时也有 i=1msi,k=Zk\sum\limits_{i=1}^ms_{i,k}=|Z_k| (对元素 kk ,枚举各个置换,查看是否不动)

则所有 ss 的和 $=\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|$。

不妨ll互不相同的等价类为 E1,E2...ElE_1,E_2...E_l ,则有 N=E1,E2...ElN=E_1,E_2...E_l

那么,由于 RRNN 的一个划分,我们可以把 i=1n\sum\limits_{i=1}^n 换成 t=1liEt\sum\limits_{t=1}^l\sum\limits_{i\in E_t}

则有 $\sum\limits_{k=1}^n|Z_k|=\sum\limits_{t=1}^l\sum\limits_{i\in E_t}|Z_i|$

回忆 定理 2.1\color{blue}\text{定理 2.1} ,由于 i,ti,t 同属于一个等价类,可以把 Zi|Z_i| 换成 Zt|Z_t|

$\sum\limits_{t=1}^l\sum\limits_{i\in E_t}|Z_t|=\sum\limits_{t=1}^l|E_t||Z_t|$

又因为 EtZt=G|E_t||Z_t|=|G| ,所以有上式 =l×G=l\times|G|

于是就有 1Gi=1mc(ai)=l\dfrac{1}{|G|}\sum\limits_{i=1}^mc(a_i)=l ,证毕。

  • Polya定理

以问题引入 : 给出一条长度为 66 的链条,每一节可以染上 44 种不同的颜色,但是翻转之后相同的方案被视为本质相同,问不同的染色方案数。

若将每种染色方案视为一个元素,令 NN 为这些元素的集合,那么 NN 在“翻转置换”作用下的等价类个数即为答案。

问题在于,置换的大小是 N=64|N|=6^4 ,非常庞大,不便于计算。

能够发现,“翻转”同样是对 1...61...6 这些“位置”的置换,且也是群。

若能把对“位置”的小置换群,和对“状态”的大置换群联系起来,就能更方便地计算了。

  • 定理 2.4:\color{blue}\text{定理 2.4}: 设有 nn 个元素,每个元素有 mm 种染色方法。

    GGnn 个元素的置换群,则染色总方案数为 :

    1GpGT(p)\dfrac{1}{|G|}\sum\limits_{p\in G}T(p)

    其中 T(p)T(p) 指在置换 pp 下,不动的染色方案数。

    • 比如 (12342143)\begin{pmatrix}1&2&3&4\\2&1&4&3\\\end{pmatrix}

      那么染成 {a,a,b,b}\{a,a,b,b\} ,置换完了之后还是 {a,a,b,b}\{a,a,b,b\} ,则称之为不动的染色方案

      染成 {a,b,c,d}\{a,b,c,d\} 置换完了之后是 {b,a,d,c}\{b,a,d,c\} ,和原来不相等,则不是“不动方案”。

  • 证明:\color{blue}\text{证明}:

    GG' 是对状态的置换群。不难发现大置换和小置换有对应关系,使用小置换对每种状态讨论即可得到大置换。

    形式化的讲,设 pGp\in G 对应 pGp'\in G'

    若一种染色方案 aa 在经过 pp 的“移动”之后,变为了 bb ,则 apba\xrightarrow{p'}b

    所以有 G=G|G|=|G'|

    根据经典的Burnside引理,可以得到答案为 1GpGc(p)\dfrac{1}{|G'|}\sum\limits_{p'\in G'}c(p')

    c(p)c(p') 的意义正是 GG相对应的置换 pp 下不动的染色方案数,证毕。

  • 接下来介绍如何求 T(p)T(p)

    d(p)d(p)pp 的循环个数,则(根据等式的传递性)每个循环中必须染上同一种颜色,且不同循环之间没有影响。

    能得到 T(p)=md(p)T(p)=m^{d(p)}

回到题目, GG 中有两个置换 : $e,\begin{pmatrix}1&2&3&4&5&6\\6&5&4&3&2&1\end{pmatrix}$。

后者有循环节 (1,2)(3,4)(5,6)(1,2)(3,4)(5,6) ,则贡献为 434^3

前者有循环节 (1)(2)(3)(4)(5)(6)(1)(2)(3)(4)(5)(6) ,则贡献为 464^6

总方案数是 12(46+43)\dfrac{1}{2}(4^6+4^3)

3. 习题

这道题里的置换就是旋转。

有旋转 0...n10...n-1 格的置换,共 nn 个。

设 $p_i=\begin{pmatrix}1&2&...&n-i&n-i+1&...&n\\1+i&2+i&...&n&1&...&i\\\end{pmatrix}$ (旋转 ii 格)

Polya式子 : 1ni=0n1nd(pi)\dfrac{1}{n}\sum\limits_{i=0}^{n-1}n^{d(p_i)}

暴力 : 根据上文介绍的方法,对每个置换缩点求循环个数 d(p)d(p) ,复杂度 O(n2)O(n^2)

打表或者拿出草稿纸画了一通后,你会发现 d(pi)=gcd(n,i)d(p_i)=\gcd(n,i)

  • 证明:\color{blue}\text{证明}: 首先注意到 d(pi)=gcd(n,i)d(p_i)=\gcd(n,i)\Longleftrightarrow 循环节大小为 ngcd(n,i)\dfrac{n}{\gcd(n,i)}

    若每次跳 ii 步,在长度为 nn 的环上,多少次才能回到原点呢?

    ini\perp n 时,可以证明 0,i,2i,3i...(n1)i0,i,2i,3i...(n-1)i(modn)\pmod n 意义下互不相同。

    此时的答案就是 nn

    i⊥̸ni\not\perp n ,采用模分类,设 d=gcd(i,n)d=\gcd(i,n) ,若从 00 开始,不难发现 d ⁣ ⁣∤ id\!\!\not|\ i 的位置都是无用的。

    这就变成了子问题 nd,id\frac{n}{d},\frac{i}{d} ,此时两者互质,答案就是 nd\frac{n}{d}

得 ${\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]$

  • 后面的 i=1n[gcd(n,i)=d]\sum\limits_{i=1}^n[\gcd(n,i)=d]

    =i=1n/d[ni]=φ(n/d)=\sum\limits_{i=1}^{n/d}[n\perp i]=\varphi(n/d)

整理得 Ans=dnφ(d)kn/d{\rm Ans}=\sum\limits_{d|n}\varphi(d)k^{n/d}

大力求欧拉函数大概是O(nlogn)O(\sqrt{n}\log n)的样子(反正快速幂也是这个复杂度)。

然而还有一个质因数分解+dfs凑出所有因数+光速幂的 O(n)O(\sqrt{n}) 解法,懒得写。

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;
}

第一眼这道题以为是子集DP\rm DP或者容斥什么的,结果数据范围 n60n\leq 60? 怕不是有多项式算法?

今早闲得无聊拿着《组合数学(第4版)》看了看,里面居然有讲到这个问题。

边 (有,无) 的状态可以看做对一个完全图染色,某条边染成黑色说明存在,染成白色就假装不存在,我们成功地把这个问题转化成了一个染色计数问题。

我们先看看式子 : 1GpGT(p)\dfrac{1}{|G|}\sum\limits_{p∈G}T(p)

我们现在是在对边计数,但是我们的置换是所有的点置换。

显然,可以由点置换构造出边置换,但是点置换的个数是 n!n! 的,无法直接枚举。我们需要找到更好的性质来批量处理。

万幸的是, 点置换循环节的构成边置换的不动点个数 有一定的关系。

考虑一个点置换,他每个循环的大小为 {S1,S2,S3,...Sm}\{S_1,S_2,S_3,...S_m\} (mm为循环节个数,且 S1S2...SmS_1\leq S_2\leq ...\leq S_m)

能够感知,所有循环节组成相同的点置换,边的等价类个数是相同的。

也就是说我们只要枚举 SS ,也就是 nn正整数拆分,就能确定一类边置换。

而正整数拆分的数量级是 O(e23nπ)O(e^{\sqrt{\frac{2}{3}n\pi}}) ,是亚指数的。本题中极限情况仅在百万级

现在,对于一组 SS ,计算出这个完全图会究竟会被分成多少个等价类,设其为 cc ,根据 Polya\rm Polya 那么不动点个数就是 2c2^c

  • 对于循环节内的边,会被分为S2\left\lfloor\dfrac{S}{2}\right\rfloor个等价类。

理解 : 我们可以把这个循环节看成一个圈,由于这个圈会转,肯定会让某些边相同。

循环内节点按 1...S1...S 编号,假设有边 (1,p)(1,p) ,那么边 (2,p+1)(2,p+1) , (3,p+2)(3,p+2) ……和 (Sp+1,S)(S-p+1,S) 肯定都和 (1,p)(1,p) 相同。

我们枚举p,会发现 p>S2p>\left\lfloor\dfrac{S}{2}\right\rfloor 的情况会和 pS2p\leq \left\lfloor\dfrac{S}{2}\right\rfloor的情况重复。

如图 : 左边 S=8S=8 ,等价类数为 82=4\left\lfloor\dfrac{8}{2}\right\rfloor=4 ; \quad 右边 S=7S=7 ,等价类数为 72=3\left\lfloor\dfrac{7}{2}\right\rfloor=3

  • 对于两个循环节之间的边,会被分为gcd(S1,S2)gcd(S_1,S_2)个等价类。

    理解 : 我们还是采用圈来理解,由于这个两个圈都会转,情况有点复杂。

    循环内节点按 1...S11...S_11...S21...S_2 编号,假设有边 (x,y)(x,y) ,那么有多少条边和这条边相同呢?

    这等价于考虑 : 这条边会在多少次置换后回到原位 ?

    答案是 lcm(S1,S2)lcm(S_1,S_2) ,如果不理解的话,想象着两个齿轮咬合着转。

    那么每个等价类的边得个数为 lcm(S1,S2)lcm(S_1,S_2) ,边的总数为 nmnm ,则等价类的总数是 nmlcm(S1,S2)=gcd(S1,S2)\dfrac{nm}{lcm(S_1,S_2)}=gcd(S_1,S_2)

如图 : 左边 S1=4,S2=2S_1=4,S_2=2 ,等价类数为 gcd(2,4)=2gcd(2,4)=2;

第一个等价类的边 (1,1),(2,2),(3,1),(4,2)(1,1),(2,2),(3,1),(4,2)

第二个等价类的边 (1,2),(2,1),(3,2),(4,1)(1,2),(2,1),(3,2),(4,1)

那么根据上述,对于循环节大小为 {S1,S2,S3,...Sm}\{S_1,S_2,S_3,...S_m\} 的点置换,其对应的边置换的贡献为:

$$\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)}}$$

我们接下来还要算循环节大小为 {S1,S2,S3,...Sm}\{S_1,S_2,S_3,...S_m\} 的点置换有几个。

我们考虑把 {1,2,3,...,n}\{1,2,3,...,n\} 分成 mm集合,大小分别为 {S1,S2,S3,...Sm}\{S_1,S_2,S_3,...S_m\}

我们考虑生成一个长为 nn 的排列,然后按照 SS 分成 mm 组,其实就是多重排列问题。

n!Πi=1mSi!\dfrac{n!}{\Pi_{i=1}^mS_i!}

如果有两个 SS 相同,是可以调换顺序的,所以还要除掉一些东西。

BiB_iS=iS=i 的个数,得 n!Πi=1mSi!Πi=1nBi!\dfrac{n!}{\Pi_{i=1}^mS_i!*\Pi_{i=1}^nB_i!}

我们还要在每个集合内连边,使得它构成一个循环。

nn 元有标号环的个数显然是 (n1)!(n-1)!

可以视作把 nn 元链首尾相,由于旋转,每个换对应 nn 个链,方案数即为 n!/n=(n1)!n!/n=(n-1)!

乘回划分集合的方案数,得到$\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)}}$$

别忘了除以置换个数 n!n!

最后注意实现复杂度和常数,小心被卡。

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]有色图