zoukankan      html  css  js  c++  java
  • [洛谷] 纯粹容器(结论/期望)

    Problem

    题目地址

    Solution

    可把题目看成:给你一条链,有 (n-1) 次删边操作,每次删边把权值较大的点留下来,求每个点期望存活轮数。(n le 50)

    结论1:(x)(i) 左边第一个权值比他大的点,(y)(i) 右边第一个权值比他大的点,点 (j)(i) 轮后被删除的的充要条件(x -> i) 或者 (i -> y) 之间所有的边均被删除,二者有一者满足条件即可。

    易证得。

    (f[i,j]) 表示第 (i)(j) 仍然存活的概率,则 (j) 的期望存活轮数 (E(j) = sum f[i,j])

    (f[i,j]) 可以用组合数求得,先求出 (j) 在第 (i) 轮死去的概率,然后用 (1) 减去。即 (i) 次删边里面选了 (x -> i) 之间所有的边的概率(i -> y)同理。注意同时选了 (x -> i)(i -> y) 的情况会被算两次,要减去一次。具体的:

    [f[i,j] = 1 - (frac{dbinom{n-1-d_1}{i-d_1}}{dbinom{n-1}{i}}+frac{dbinom{n-1-d_2}{i-d_2}}{dbinom{n-1}{i}}-frac{dbinom{n-1-d_1-d_2}{i-d_1-d_2}}{dbinom{n-1}{i}}) ]

    其中,(d_1=i-x,d_2=y-i),分别 (i) 到左右两边比他大的点之间的边数。

    预处理 (O(n^2)),计算 (f[i,j])(E(j)) 的复杂度 (O(n^2)),时间复杂度 (O(n^2))

    Code

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    #define int long long
    #define INF 0x3f3f3f3f
    using namespace std;
    inline int read() {
        int x = 0, f = 1; char ch = getchar();
        while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
        return x * f;
    }
    const int N = 57, mod = 998244353;
    int n;
    int a[N],d1[N],d2[N],ans[N];
    int f[N][N],c[N][N];
    void Init() {
    	for(int i=0;i<=n;++i) c[i][0] = 1;
    	for(int i=1;i<=n;++i) {
    		for(int j=1;j<=i;++j) {
    			c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod;
    		}
    	}
    	a[0] = a[n+1] = INF;
    	for(int i=1;i<=n;++i) {
    		for(int j=i-1;j>=0;--j) {
    			if(a[j] > a[i]) {
    				d1[i] = (j>0 ? i - j : INF); break;
    			}
    		}
    		for(int j=i+1;j<=n+1;++j) {
    			if(a[j] > a[i]) {
    				d2[i] = (j<=n ? j - i : INF); break;
    			}
    		}
    	}
    }
    int Pow(int x,int y) {
    	int res = 1, base = x;
    	while(y) {
    		if(y&1) res = res*base%mod; base = base*base%mod; y >>= 1;
    	}
    	return res;
    }
    int Inv(int x) {
    	return Pow(x,mod-2);
    }
    signed main()
    {
    	n = read();
    	for(int i=1;i<=n;++i) a[i] = read();
    	Init();
    	for(int i=1;i<n;++i) {
    		for(int j=1;j<=n;++j) {
    			int x = (d1[j]>i ? 0 : c[n-1-d1[j]][i-d1[j]]*Inv(c[n-1][i])%mod);
    			int y = (d2[j]>i ? 0 : c[n-1-d2[j]][i-d2[j]]*Inv(c[n-1][i])%mod);
    			int z = (d1[j]+d2[j]>i ? 0 : c[n-1-d1[j]-d2[j]][i-d1[j]-d2[j]]*Inv(c[n-1][i])%mod);
    			f[i][j] = (1 - (x+y-z + mod)%mod + mod) % mod;
    		}
    	}
    	for(int i=1;i<n;++i) {
    		for(int j=1;j<=n;++j) {
    			ans[j] = (ans[j] + f[i][j]) % mod;
    		}
    	}
    	for(int i=1;i<=n;++i) printf("%lld ",ans[i]);
        return 0;
    }
    /*
    5
    1 4 2 3 5
    
    499122178 249561091 665496236 582309207 4
    */
    

    Summary

    推结论/性质,还是多做题!

  • 相关阅读:
    JSONP(处理跨域问题)
    Bootstrap 按钮
    input file 图片上传展示重新上传
    Bootstrap 表单
    Bootstrap 表格
    Bootstrap 代码
    Bootstrap 排版 文本
    bootstrap 栅格calss
    Bootsrap 直接使用
    Bootstrap3和Bootsrap4的区别
  • 原文地址:https://www.cnblogs.com/BaseAI/p/14006050.html
Copyright © 2011-2022 走看看