gmoj 7010. 2021.03.13【2021省赛模拟】graph

题目

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=12i2ijiij(fj+fij+1)+j=0+(n2i2)j=j=12ii22j(ij)(fj+fij+1)+n2i2n2

但是这样会算重:假设这个连通块由三个部分 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=1n21gn,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个问题:

  1. 为什么要乘上 ( n − 1 i − 1 ) ( k j ) \tbinom{n-1}{i-1} \tbinom{k}{j} (i1n1)(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)} (nni)2(kj) 中,如果边的组合方式不同或点的编号不同,就会被视作不同的方案。
  2. 为什么有了 ( 1 − f i , j ) (1-f_{i,j}) (1fi,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=1n1j=0k(i1n1)(1fi,j)(jk)(ni)2j(nni)2(kj)=i=1n1(i1n1)j=0k1l=0i21gi,l(i2l)j(jk)(ni)2j(nni)2(kj)=i=1n1(i1n1)j=0k(ni)2jl=0i21gi,l(n2l)j(jk)(nni)2(kj)

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(ni)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=0k(ni)2jl=0i21gi,l(n2l)j(jk)(nni)2(kj)j=0kxjl=0i21gi,l(n2l)j(jk)ykjj=0kxjykj(jk)l=0i21gi,lj=0k(n2l)jykj(jk)(x+y)kl=0i21gi,l(n2l+y)k[n2i2+(ni)2]kl=0i21gi,l[n2l+(ni)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=1n1(i1n1)[n2i2+(ni)2]kl=0i21gi,l[n2l+(ni)2]k
对于一个 i i i ,它会让 g n , i 2 + ( n − i ) 2 g_{n,i^2+(n-i)^2} gn,i2+(ni)2 加上 ( n − 1 i − 1 ) \tbinom{n-1}{i-1} (i1n1) ,让 g n , l + ( n − i ) 2 g_{n,l+(n-i)^2} gn,l+(ni)2 减去 ( n − 1 i − 1 ) g i , l \tbinom{n-1}{i-1}g_{i,l} (i1n1)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=0n21gn,i(n2i)k=i=0n21gn,in21n2

时间复杂度 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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值