题目链接
题目解法
可以参考这篇博客
看到同构、重新标号,首先想到置换然后用
b
u
r
n
s
i
d
e
burnside
burnside 引理
考虑将边染色,出现在图中的为 1,未出现的为 0
考虑一个已经固定的置换的等价类个数
一、将图拆分成若干个置换环
一个
n
n
n 个点的置换必定可以拆分成若干个置换环,其大小分别为
b
1
,
b
2
,
.
.
.
,
b
m
b_1,b_2,...,b_m
b1,b2,...,bm
二、计算环内的等价类个数
考虑将点旋转之后,长度相同的边必定在同一个等价类中(这里把边做置换,与上面把点置换不同),一个
n
n
n 个点的完全图中长度不同的边的个数共有
n
2
\frac{n}{2}
2n 条,所以环内的等价类个数为
∑
⌊
b
i
2
⌋
\sum \lfloor \frac{b_i}{2}\rfloor
∑⌊2bi⌋
这里可以借用一下这张图,来更好地理解(其中同种颜色的边属于同一个等价类):
三、计算环与环之间的等价类个数
先考虑大小为
4
,
6
4,6
4,6 的环,用前一个数表示环 1 中的点,后一个数表示环 2 中的点,那么
(
1
,
1
)
,
(
2
,
2
)
,
(
3
,
3
)
,
(
4
,
4
)
,
(
1
,
5
)
,
(
2
,
6
)
,
(
3
,
1
)
,
.
.
.
(1,1),(2,2),(3,3),(4,4),(1,5),(2,6),(3,1),...
(1,1),(2,2),(3,3),(4,4),(1,5),(2,6),(3,1),... 都属于同一个等价类,在这个例子中,等价类的个数为 2
对于大小分别为
s
1
,
s
2
s_1,s_2
s1,s2 的两个环,其中每个等价类中有
[
s
1
,
s
2
]
[s1,s2]
[s1,s2] 个点,那么共有
s
1
∗
s
2
[
s
1
,
s
2
]
=
(
s
1
,
s
2
)
\frac{s1*s2}{[s1,s2]}=(s1,s2)
[s1,s2]s1∗s2=(s1,s2) 个等价类
所以对于一个固定的置换,等价类的个数即为 ∑ i = 1 m ⌊ b i 2 ⌋ + ∑ i = 1 m ∑ j = 1 i − 1 ( b i , b j ) \sum_{i=1}^{m} \lfloor \frac{b_i}{2}\rfloor+\sum_{i=1}^{m}\sum_{j=1}^{i-1}(b_i,b_j) ∑i=1m⌊2bi⌋+∑i=1m∑j=1i−1(bi,bj)
计算对于每一个固定的
b
1
,
.
.
.
,
b
m
b_1,...,b_m
b1,...,bm 的方案数
记
b
i
b_i
bi 出现了
c
i
c_i
ci 次(下文的
c
i
c_i
ci 认为是对不同的
b
i
b_i
bi,即相同的
b
i
b_i
bi 只计算一次
c
i
c_i
ci)
考虑总共有
n
!
n!
n! 种置换(
1
−
n
1-n
1−n 随意匹配)
考虑每个长度为
b
b
b 的循环会重复出现
b
!
b!
b! 次,因为点的顺序不影响
b
b
b 的大小
所以
1
−
n
1-n
1−n 分给
m
m
m 个循环的方案数为
n
!
Π
(
b
i
!
)
\frac{n!}{\Pi(b_i!)}
Π(bi!)n!
考虑相同的
b
b
b 之间可能会有重复,例如
(
1
,
2
)
(
3
,
4
)
(1,2)(3,4)
(1,2)(3,4) 与
(
3
,
4
)
(
1
,
2
)
(3,4)(1,2)
(3,4)(1,2) 是同一种方案,只不过顺序不同,所以方案数需除以
Π
(
c
i
!
)
\Pi (c_i!)
Π(ci!)
考虑置换内部可以重新排序,又因为置换是一个环,所以方案数需要乘
Π
(
b
i
−
1
)
!
\Pi(b_i-1)!
Π(bi−1)!
所以最终的方案数为
n
!
Π
(
b
i
!
)
∗
Π
(
c
i
!
)
∗
Π
(
b
i
−
1
)
!
\frac{n!}{\Pi(b_i!)*\Pi (c_i!)}*\Pi(b_i-1)!
Π(bi!)∗Π(ci!)n!∗Π(bi−1)!,即为
n
!
Π
b
i
∗
Π
(
c
i
!
)
\frac{n!}{\Pi b_i*\Pi (c_i!)}
Πbi∗Π(ci!)n!
根据
b
u
r
n
s
i
d
e
burnside
burnside 引理,不动点个数即为
∑
n
!
Π
b
i
∗
Π
(
c
i
!
)
∗
2
k
\sum \frac{n!}{\Pi b_i*\Pi (c_i!)}*2^k
∑Πbi∗Π(ci!)n!∗2k
其中
k
=
∑
i
=
1
m
⌊
b
i
2
⌋
+
∑
i
=
1
m
∑
j
=
1
i
−
1
(
b
i
,
b
j
)
k=\sum_{i=1}^{m} \lfloor \frac{b_i}{2}\rfloor+\sum_{i=1}^{m}\sum_{j=1}^{i-1}(b_i,b_j)
k=∑i=1m⌊2bi⌋+∑i=1m∑j=1i−1(bi,bj)
所以
A
n
s
=
1
n
!
∗
∑
n
!
Π
b
i
∗
Π
(
c
i
!
)
∗
2
k
=
∑
2
k
Π
b
i
∗
Π
(
c
i
!
)
Ans=\frac{1}{n!}*\sum \frac{n!}{\Pi b_i*\Pi (c_i!)}*2^k=\sum \frac{2^k}{\Pi b_i*\Pi (c_i!)}
Ans=n!1∗∑Πbi∗Π(ci!)n!∗2k=∑Πbi∗Π(ci!)2k
因为只需要枚举不同的 b 1 , . . . , b m b_1,...,b_m b1,...,bm 所以时间是可以过的(具体我也分析不出来)
#include <bits/stdc++.h>
using namespace std;
const int N(70),P(997);
int n,ans,b[N],c[N];
int inv[N],facinv[N],bs2[2000];
inline int read(){
int FF=0,RR=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
return FF*RR;
}
void dfs(int dep,int las){
if(!las){
int k=0;
for(int i=1;i<dep;i++){
k+=b[i]/2;
for(int j=1;j<i;j++) k+=__gcd(b[i],b[j]);
}
int res=bs2[k];
for(int i=1;i<dep;i++) res=res*inv[b[i]]%P;
for(int i=1;i<dep;i++) if(b[i]!=b[i-1]) res=res*facinv[c[b[i]]]%P;
ans=(ans+res)%P;
return;
}
for(int i=max(1,b[dep-1]);i<=las;i++){
b[dep]=i,c[i]++;
dfs(dep+1,las-i);
c[i]--;
}
}
int main(){
n=read();
inv[1]=1,facinv[1]=1;
for(int i=2;i<N;i++) inv[i]=(P-P/i)*inv[P%i]%P,facinv[i]=facinv[i-1]*inv[i]%P;
bs2[0]=1;
for(int i=1;i<2000;i++) bs2[i]=bs2[i-1]*2%P;
dfs(1,n);
printf("%d",ans);
return 0;
}