题目
https://gmoj.net/senior/#main/show/7010
题解
考场上的思路是设
f
i
f_i
fi 表示组成一个大小为
i
i
i 的连通块的期望步数,然后考虑这个连通块一开始是由哪两个小连通块连接而成的。有状态转移方程:
f
i
=
∑
j
=
1
⌊
i
2
⌋
2
⋅
j
i
⋅
i
−
j
i
⋅
(
f
j
+
f
i
−
j
+
1
)
+
∑
j
=
0
+
∞
(
i
2
n
2
)
j
=
∑
j
=
1
⌊
i
2
⌋
2
j
(
i
−
j
)
i
2
⋅
(
f
j
+
f
i
−
j
+
1
)
+
n
2
n
2
−
i
2
\begin{aligned} f_i&=\sum_{j=1}^{\left\lfloor\frac{i}{2}\right\rfloor} 2\cdot\frac{j}{i}\cdot\frac{i-j}{i}\cdot(f_j+f_{i-j}+1)+\sum_{j=0}^{+\infty} \left(\frac{i^2}{n^2} \right)^j\\ &=\sum_{j=1}^{\left\lfloor\frac{i}{2}\right\rfloor} \frac{2j(i-j)}{i^2}\cdot(f_j+f_{i-j}+1)+\frac{n^2}{n^2-i^2} \end{aligned}
fi=j=1∑⌊2i⌋2⋅ij⋅ii−j⋅(fj+fi−j+1)+j=0∑+∞(n2i2)j=j=1∑⌊2i⌋i22j(i−j)⋅(fj+fi−j+1)+n2−i2n2
但是这样会算重:假设这个连通块由三个部分 X , Y , Z X,Y,Z X,Y,Z 组成, X , Y X,Y X,Y 之间、 X , Z X,Z X,Z 之间、 Y , Z Y,Z Y,Z 之间各有一条边。那么连边顺序 ( X , Y ) → ( Y , Z ) (X,Y)\to (Y,Z) (X,Y)→(Y,Z) 和连边顺序 ( Y , Z ) → ( X , Y ) (Y,Z)\to (X,Y) (Y,Z)→(X,Y) 都会被当作不同的方案。
正解是设 f n , k f_{n,k} fn,k 表示组成一个 n n n 个点、 k k k 条边的 不连通图 的 概率 。
这样答案就是 ∑ k = 0 + ∞ f n , k \sum_{k=0}^{+\infty} f_{n,k} ∑k=0+∞fn,k 。这个式子的含义是如果放了 k k k 条边仍然不连通就要再多加一条边,因此不同于其它由概率求期望的情况,这里不用乘上 k k k 。
发现
f
n
,
k
f_{n,k}
fn,k 可以 容斥 。设 容斥系数 为
g
g
g ,那么有
f
n
,
k
=
∑
i
=
1
n
2
−
1
g
n
,
i
(
i
n
2
)
k
f_{n,k}=\sum_{i=1}^{n^2-1} g_{n,i} \left(\frac{i}{n^2} \right)^k
fn,k=i=1∑n2−1gn,i(n2i)k
上式的意思是对于一组不同的
u
,
v
u,v
u,v ,如果把边
(
u
,
v
)
(u,v)
(u,v) 和边
(
u
,
v
)
(u,v)
(u,v) 分别视作两条边,那么一共有
n
2
n^2
n2 条边(这样子做是为了方便转移)。我们枚举图中出现了的边的种类
i
i
i ,就可以得到上式。
但是怎么求 g g g 呢?这需要另一种 f f f 的转移。
另一种转移思路是考虑构造编号为 1 1 1 的点所在的连通块,那么剩下的点就可以随便搞了。
关于下式有2个问题:
- 为什么要乘上 ( n − 1 i − 1 ) ( k j ) \tbinom{n-1}{i-1} \tbinom{k}{j} (i−1n−1)(jk) ?是因为在 ( i n ) 2 j \left(\frac{i}{n}\right)^{2j} (ni)2j 和 ( n − i n ) 2 ( k − j ) \left(\frac{n-i}{n}\right)^{2(k-j)} (nn−i)2(k−j) 中,如果边的组合方式不同或点的编号不同,就会被视作不同的方案。
- 为什么有了 ( 1 − f i , j ) (1-f_{i,j}) (1−fi,j) 还要乘上 ( i n ) 2 j \left(\frac{i}{n}\right)^{2j} (ni)2j ?是因为 f i , j f_{i,j} fi,j 中有一个项 ( x i ) 2 j \left(\frac{x}{i}\right)^{2j} (ix)2j ,显然我们要把分母改成 n n n ,因此就要乘上它。
f n , k = ∑ i = 1 n − 1 ∑ j = 0 k ( n − 1 i − 1 ) ( 1 − f i , j ) ( k j ) ( i n ) 2 j ( n − i n ) 2 ( k − j ) = ∑ i = 1 n − 1 ( n − 1 i − 1 ) ∑ j = 0 k [ 1 − ∑ l = 0 i 2 − 1 g i , l ( l i 2 ) j ] ( k j ) ( i n ) 2 j ( n − i n ) 2 ( k − j ) = ∑ i = 1 n − 1 ( n − 1 i − 1 ) ∑ j = 0 k [ ( i n ) 2 j − ∑ l = 0 i 2 − 1 g i , l ( l n 2 ) j ] ( k j ) ( n − i n ) 2 ( k − j ) \begin{aligned} f_{n,k} &= \sum_{i=1}^{n-1} \sum_{j=0}^k \binom{n-1}{i-1}(1-f_{i,j})\binom{k}{j}\left(\frac{i}{n}\right)^{2j}\left(\frac{n-i}{n}\right)^{2(k-j)}\\ &= \sum_{i=1}^{n-1} \binom{n-1}{i-1} \sum_{j=0}^k \left[1-\sum_{l=0}^{i^2-1}g_{i,l}\left(\frac{l}{i^2} \right)^j \right] \binom{k}{j}\left(\frac{i}{n}\right)^{2j}\left(\frac{n-i}{n}\right)^{2(k-j)}\\ &= \sum_{i=1}^{n-1} \binom{n-1}{i-1} \sum_{j=0}^k \left[\left(\frac{i}{n} \right)^{2j} -\sum_{l=0}^{i^2-1}g_{i,l}\left(\frac{l}{n^2} \right)^j \right] \binom{k}{j}\left(\frac{n-i}{n}\right)^{2(k-j)} \end{aligned} fn,k=i=1∑n−1j=0∑k(i−1n−1)(1−fi,j)(jk)(ni)2j(nn−i)2(k−j)=i=1∑n−1(i−1n−1)j=0∑k⎣⎡1−l=0∑i2−1gi,l(i2l)j⎦⎤(jk)(ni)2j(nn−i)2(k−j)=i=1∑n−1(i−1n−1)j=0∑k⎣⎡(ni)2j−l=0∑i2−1gi,l(n2l)j⎦⎤(jk)(nn−i)2(k−j)
设
x
=
i
2
n
2
,
y
=
(
n
−
i
)
2
n
2
x=\cfrac{i^2}{n^2},y=\cfrac{(n-i)^2}{n^2}
x=n2i2,y=n2(n−i)2 ,那么
∑
j
=
0
k
[
(
i
n
)
2
j
−
∑
l
=
0
i
2
−
1
g
i
,
l
(
l
n
2
)
j
]
(
k
j
)
(
n
−
i
n
)
2
(
k
−
j
)
=
∑
j
=
0
k
[
x
j
−
∑
l
=
0
i
2
−
1
g
i
,
l
(
l
n
2
)
j
]
(
k
j
)
y
k
−
j
=
∑
j
=
0
k
x
j
y
k
−
j
(
k
j
)
−
∑
l
=
0
i
2
−
1
g
i
,
l
∑
j
=
0
k
(
l
n
2
)
j
y
k
−
j
(
k
j
)
=
(
x
+
y
)
k
−
∑
l
=
0
i
2
−
1
g
i
,
l
(
l
n
2
+
y
)
k
=
[
i
2
+
(
n
−
i
)
2
n
2
]
k
−
∑
l
=
0
i
2
−
1
g
i
,
l
[
l
+
(
n
−
i
)
2
n
2
]
k
\begin{aligned} &\sum_{j=0}^k \left[\left(\frac{i}{n} \right)^{2j} -\sum_{l=0}^{i^2-1}g_{i,l}\left(\frac{l}{n^2} \right)^j \right] \binom{k}{j}\left(\frac{n-i}{n}\right)^{2(k-j)}\\ =&\sum_{j=0}^k \left[x^j - \sum_{l=0}^{i^2-1}g_{i,l} \left(\frac{l}{n^2} \right)^j \right] \binom{k}{j} y^{k-j}\\ =&\sum_{j=0}^k x^j y^{k-j} \binom{k}{j} - \sum_{l=0}^{i^2-1}g_{i,l} \sum_{j=0}^k \left(\frac{l}{n^2} \right)^j y^{k-j} \binom{k}{j}\\ =& (x+y)^k - \sum_{l=0}^{i^2-1} g_{i,l} \left(\frac{l}{n^2} +y\right)^k\\ =& \left[\frac{i^2+(n-i)^2}{n^2}\right]^k - \sum_{l=0}^{i^2-1} g_{i,l} \left[\frac{l+(n-i)^2}{n^2}\right]^k \end{aligned}
====j=0∑k⎣⎡(ni)2j−l=0∑i2−1gi,l(n2l)j⎦⎤(jk)(nn−i)2(k−j)j=0∑k⎣⎡xj−l=0∑i2−1gi,l(n2l)j⎦⎤(jk)yk−jj=0∑kxjyk−j(jk)−l=0∑i2−1gi,lj=0∑k(n2l)jyk−j(jk)(x+y)k−l=0∑i2−1gi,l(n2l+y)k[n2i2+(n−i)2]k−l=0∑i2−1gi,l[n2l+(n−i)2]k
所以
f
n
,
k
=
∑
i
=
1
n
−
1
(
n
−
1
i
−
1
)
{
[
i
2
+
(
n
−
i
)
2
n
2
]
k
−
∑
l
=
0
i
2
−
1
g
i
,
l
[
l
+
(
n
−
i
)
2
n
2
]
k
}
f_{n,k}=\sum_{i=1}^{n-1} \binom{n-1}{i-1} \left\{\left[\frac{i^2+(n-i)^2}{n^2}\right]^k - \sum_{l=0}^{i^2-1} g_{i,l} \left[\frac{l+(n-i)^2}{n^2}\right]^k \right\}
fn,k=i=1∑n−1(i−1n−1)⎩⎨⎧[n2i2+(n−i)2]k−l=0∑i2−1gi,l[n2l+(n−i)2]k⎭⎬⎫
对于一个
i
i
i ,它会让
g
n
,
i
2
+
(
n
−
i
)
2
g_{n,i^2+(n-i)^2}
gn,i2+(n−i)2 加上
(
n
−
1
i
−
1
)
\tbinom{n-1}{i-1}
(i−1n−1) ,让
g
n
,
l
+
(
n
−
i
)
2
g_{n,l+(n-i)^2}
gn,l+(n−i)2 减去
(
n
−
1
i
−
1
)
g
i
,
l
\tbinom{n-1}{i-1}g_{i,l}
(i−1n−1)gi,l 。
那么怎么求答案呢?
a
n
s
=
∑
k
=
0
+
∞
f
n
,
k
=
∑
k
=
0
+
∞
∑
i
=
0
n
2
−
1
g
n
,
i
(
i
n
2
)
k
=
∑
i
=
0
n
2
−
1
g
n
,
i
⋅
n
2
n
2
−
1
\begin{aligned} ans&=\sum_{k=0}^{+\infty} f_{n,k}\\ &= \sum_{k=0}^{+\infty}\sum_{i=0}^{n^2-1} g_{n,i} \left(\frac{i}{n^2}\right)^k\\ &=\sum_{i=0}^{n^2-1} g_{n,i}\cdot \frac{n^2}{n^2-1} \end{aligned}
ans=k=0∑+∞fn,k=k=0∑+∞i=0∑n2−1gn,i(n2i)k=i=0∑n2−1gn,i⋅n2−1n2
时间复杂度 O ( N 4 ) O(N^4) O(N4) (求 g g g 时枚举 n , i , l n,i,l n,i,l 的复杂度)。
这道题比较妙的地方在于 f f f 是求不出来的,就用 g g g 来辅助转移、求答案。
代码
#include<cstdio>
using namespace std;
#define fo(i,l,r) for(i=l;i<=r;++i)
#define M 10005
#define N 105
int P,g[N][M],fac[M],ifac[M],inv[M];
inline int C(int x,int y){return 1LL*fac[x]*ifac[y]%P*ifac[x-y]%P;}
inline void add(int &x,int y){x+=y;if(x>=P) x-=P;}
int main()
{
freopen("graph.in","r",stdin);
freopen("graph.out","w",stdout);
int i,j,k,x,y,ans=0,n,m;
scanf("%d%d",&n,&P),m=n*n;
fac[0]=1;fo(i,1,m) fac[i]=1LL*fac[i-1]*i%P;
inv[1]=1;fo(i,2,m) inv[i]=1LL*inv[P%i]*(P-P/i)%P;
ifac[0]=1;fo(i,1,m) ifac[i]=1LL*ifac[i-1]*inv[i]%P;
fo(k,1,n) fo(i,1,k-1)
{
x=C(k-1,i-1),y=(k-i)*(k-i);
add(g[k][i*i+y],x);
fo(j,0,i*i-1)
add(g[k][j+y],P-1LL*g[i][j]*x%P);
}
fo(i,0,m-1) add(ans,1LL*g[n][i]*n*n%P*inv[n*n-i]%P);
printf("%d\n",ans);
return 0;
}