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 ;
    }
    
  • 相关阅读:
    oracle——定时器时间设置
    Servlet上下文监听
    jsp开发中页面数据共享技术
    String类的创建
    Microsoft Enterprise Library 5.0 系列 Configuration Application Block
    How to print only the selected grid rows
    企业库的保存方法
    devexpress pictureedit 按钮调用其菜单功能
    Devexpress IDE 插件 卸载
    修改安装包快捷方式路径
  • 原文地址:https://www.cnblogs.com/Soulist/p/13848734.html
Copyright © 2011-2022 走看看