zoukankan      html  css  js  c++  java
  • [ZJOI2015]地震后的幻想乡

    [ZJOI2015]地震后的幻想乡

    给定一张图,每条边的边权在 ([0,1]) 中随机,求最小生成树的最大边权的期望。

    (nle 10,mle frac{n(n-1)}{2})

    Solution

    这个题大概代表了七月份的一点学习记录,今天准备整理一下。不过按照这个方法推下来好 easy(无脑) 啊

    对于连续型随机变量,我们一般使用概率密度函数 (f(x)) 来描述它取值的概率,其一定区域的积分可以表示取值为连续的一段区间的概率。

    例如,论证 (mathbb{E}(max{x_1,x_2...x_n})=frac{n}{n+1}) 时,我们先定义 (F(x)=max{x_1...x_n}le x),那么容易得到 (F(x)=x^n)

    我们不难观察到,(F(x)) 的导数就是其对应的密度函数 (f(x))

    所以我们得到 (f(x)=x^{n-1}n)

    容易观察得到,我们计算的期望为:

    [egin{aligned} &int_0^1 xf(x)cdot dx \&=int_0^1 x^nncdot dx \&=frac{n}{n+1} end{aligned}]

    接下来我们考虑证明题面给出的性质,注意到我们计算的是集合的 (min_k),所以我们可以考虑通过拓展 (min-max) 容斥来计算答案:

    [egin{aligned} &E(min_k(x))=sum_{i=k}^n inom{n}{i}inom{i-1}{k-1}(-1)^{i-k}frac{i}{i+1} \&=ksum_{i=k}^n inom{n}{i}inom{i}{k}(-1)^{i-k}frac{1}{i+1} \&={k}inom{n}{k}sum_{i=k}^n inom{n-k}{i-k}(-1)^{i-k}frac{1}{i+1} \&={k} inom{n}{k}sum_{j=0}^{n-k} inom{n-k}{j} (-1)^j frac{1}{j+k+1} end{aligned}]

    (m=n-k)

    [egin{aligned} &{k} inom{n}{k}sum_{j=0}^{m} inom{m}{j} (-1)^j frac{1}{j+k+1} \&={k} inom{n}{k} sum_{j=0}^m inom{m}{j} (-1)^j int_0^1 x^{j+k} \&={k}inom{n}{k}sum_{j=0}^m inom{m}{j}int_0^1 x^k(-x)^j \&={k}inom{n}{k}int_0^1 x^ksum_j^m(-x)^j inom{m}{j} \&={k}inom{n}{k}int_0^1 x^k(1-x)^m \&={k} imes frac{n!}{k!(n-k)!} imes frac{k!m!}{(m+k+1)!} \&=frac{k}{n+1} end{aligned}]

    于是得证。

    最后一步是分部积分的结论,下面也给出证明:

    考虑:

    [egin{aligned} &f(x)g(x)=int f'(x)g(x)+int f(x)g'(x) \&int f'(x)g(x)=f(x)g(x)-int f(x)g'(x) end{aligned}]

    (B(a+b,b)=int_0^1 x^a(1-x)^b),那么不难发现:

    • (f(x)=frac{x^a}{a+1},g(x)=(1-x)^b)

    [egin{aligned} &B(a+b,b)=int_0^1 f'(x)g(x) \&=f(1)g(1)-int_0^1 f(x)g'(x) \&=-int_0^1 frac{x^{a+1}}{a+1} imes (-b(1-x)^{b-1}) \&=frac{b}{a+1}int_0^1 x^{a+1}(1-x)^{b-1} \&=frac{b}{a+1}B(a+b,b-1) end{aligned}]

    观察到 (B(a+b,0)=int_0^1 x^{a+b}=frac{1}{a+b+1}),不难得到 (B(a+b,b)=frac{b!}{(a+b+1)^{underline{b+1}}}=frac{a!b!}{(a+b+1)!})

    至此,命题得证。


    注意到答案是:

    [int_0^1 dx imes P(X=x)x ]

    构造 (g(x)=P(Xle x)),那么 (P(X=x))(g(x)) 的导数。

    于是答案即为:

    [int_0^1 dxcdot g'(x)x=g(x)x-int_0^1 dxcdot g(x) ]

    不难发现答案即为:

    [1-int_0^1 dxcdot P(Xle x) ]

    后者等价于仅保留小于 (x) 的边有此图联通。

    可以基于这样的考量,我们给每条边赋予 (0/1) 的权值表示他是否小于等于 (x),如果为 (1) 那么小于等于 (x),不妨假设有 (a)(1) 边和 ((m-a))(0) 边,此时概率角度的贡献为:

    [x^a(1-x)^{m-a} ]

    对于某个具体的 (a),我们相当于计算:

    [int_0^1 x^a(1-x)^{m-a}=frac{a!(m-a)!}{(m+1)!} ]

    于是我们成功的再次通过分部积分将此问题转换为给边染色,恰好染 (a) 条黑色边使得这张图联通的方案数。

    等价于求这张图的恰好 (a) 条边的联通子图的数量。

    经典的容斥手段是对于子集 (S) 先任意保留边,在枚举 (1) 号点所在的连通块,这里我们还需要枚举 (1) 所在的连通块所保留的边数,此时外部的边数是固定的,然后转移,复杂度为 (mathcal O(3^ncdot m^2))

    不难发现转移的时候的卷积为子集卷积,可以通过 FWT 处理做到 (mathcal O(2^nn^2cdot m^2)),不过意义不大。

    (Code:)

    #include<bits/stdc++.h>
    using namespace std ;
    #define Next( i, x ) for( register int i = head[x]; i; i = e[i].next )
    #define rep( i, s, t ) for( register int i = (s); i <= (t); ++ i )
    #define drep( i, s, t ) for( register int i = (t); i >= (s); -- i )
    #define re register
    int gi() {
    	char cc = getchar() ; int cn = 0, flus = 1 ;
    	while( cc < '0' || cc > '9' ) {  if( cc == '-' ) flus = - flus ; cc = getchar() ; }
    	while( cc >= '0' && cc <= '9' )  cn = cn * 10 + cc - '0', cc = getchar() ;
    	return cn * flus ;
    }
    const int N = 10 + 5 ; 
    const int M = 60 ; 
    int n, m, lim, g[1 << 11] ; 
    long double f[1 << 11][M], C[M][M], fac[M] ; 
    signed main()
    {
    	n = gi(), m = gi() ; int x, y ; 
    	rep( i, 1, m ) 
    		x = gi() - 1, y = gi() - 1, 
    		++ g[(1 << x) | (1 << y)] ;
    	lim = (1 << n) ;
    	for(re int k = 1; k < lim; k <<= 1 ) 
    	rep( i, 0, lim ) if(i & k) g[i] += g[i ^ k] ; 
    	C[0][0] = 1, f[0][0] = 1, fac[0] = 1 ; 
    	rep( i, 1, m ) rep( j, 0, i ) C[i][j] = (!j) ? 1 : C[i - 1][j - 1] + C[i - 1][j] ; 
    	rep( i, 1, m + 1 ) fac[i] = fac[i - 1] * i ; 
    	for(re int S = 1; S < lim; ++ S) {
    		int p = n ;
    		rep( j, 0, n - 1 ) if((1 << j) & S) { p = j ; break ; } 
    		rep( j, 0, m ) f[S][j] = C[g[S]][j] ; 
    		for(re int i = S; i; i = (i - 1) & S) {
    			if((!(i & (1 << p))) || (i == S)) continue ; 
    			int u = S ^ i, l = g[i], r = g[u] ; 
    			rep( j, 0, l ) rep( k, 0, r ) 
    			f[S][j + k] -= f[i][j] * C[r][k] ;
    		}
    	}
    	long double Ans = 1 ; -- lim ; 
    	rep( j, 0, m ) Ans -= f[lim][j] / fac[m + 1] * fac[j] * fac[m - j] ;
    	printf("%.6Lf
    ", Ans ) ; 
    	return 0 ;
    }
    
  • 相关阅读:
    HDU 5818 Joint Stacks
    HDU 5816 Hearthstone
    HDU 5812 Distance
    HDU 5807 Keep In Touch
    HDU 5798 Stabilization
    HDU 5543 Pick The Sticks
    Light OJ 1393 Crazy Calendar (尼姆博弈)
    NEFU 2016省赛演练一 I题 (模拟题)
    NEFU 2016省赛演练一 F题 (高精度加法)
    NEFU 2016省赛演练一 B题(递推)
  • 原文地址:https://www.cnblogs.com/Soulist/p/13848734.html
Copyright © 2011-2022 走看看