zoukankan      html  css  js  c++  java
  • [CF643E]Bear and Destroying Subtrees(期望,忽略误差)

    Description:

    ​ 给你一棵初始只有根为1的树

    ​ 两种操作

    1 x 表示加入一个新点以 x为父亲

    2 x 表示以 x 为根的子树期望最深深度

    ​ 每条边都有 (frac{1}{2}) 的概率断裂。

    Solution:

    [E(max{A}) ot=max{E(A)} ]

    ​ 所以一般会从定义出发,设 (dp[x][i]) 表示以 (x) 为根,深度为 (i) 的概率。

    ​ 然后不好确定这个深度是在哪取到,所以可以设 (dp[x][i]) 为深度 (le i) 的概率,不难发现这样每个子树就是独立的了。

    [dp[x][i] = prod_{vin son(x)}frac{dp[x][i - 1] + 1}{2} ]

    ​ 加1是因为 ((x, v)) 这条边可能会断,那么如果断了,那么 (deple i - 1) 的概率一定是1。

    ​ 深度较大时期望值很小(它的缩减率是指数级的), 因为允许精度误差所以可以忽略. 加入每个点时把上面 50 个祖先的 (dp) 值更新一下即可。

    Summary:

    ​ 在难以刻画细小的状态时可以将状态设广范些,但要保证前后可以互相转换。

    Code:

    #include <vector>
    #include <cmath>
    #include <cstdio>
    #include <cassert>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    typedef long long LL;
    typedef unsigned long long uLL;
    
    #define fir first
    #define sec second
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define MP(x, y) std::make_pair(x, y)
    #define PB(x) push_back(x)
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    #define GO cerr << "GO" << endl;
    #define DE(x) cerr << x << endl;
    #define rep(i, a, b) for (register int i = (a), i##_end_ = (b); (i) <= i##_end_; ++ (i))
    #define drep(i, a, b) for (register int i = (a), i##_end_ = (b); (i) >= i##_end_; -- (i))
    #define REP(i, a, b) for (register int i = (a), i##_end_ = (b); (i) < i##_end_; ++ (i))
    
    inline int read() {
        register int x = 0; register int f = 1; register char c;
        while (!isdigit(c = getchar())) if (c == '-') f = -1;
        while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
        return x * f;
    }
    
    template<class T> inline void write(T x) {
        static char stk[30]; static int top = 0;
        if (x < 0) { x = -x, putchar('-'); }
        while (stk[++top] = x % 10 xor 48, x /= 10, x);
        while (putchar(stk[top--]), top);
    }
    
    template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
    template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
    
    using namespace std;
    
    const int maxN = 5e5 + 1;
    const int D = 50;
    
    int Q, fa[maxN], ncnt;
    double dp[maxN][D];
    
    void clear(int x, int son, int cnt)
    {
    	if (!x || cnt >= D) return;
    	clear(fa[x], x, cnt + 1);
    	for (int i = 1; i < D; ++i)
    		dp[x][i] /= 0.5 * (dp[son][i - 1] + 1);
    }
    
    void update(int x, int son, int cnt)
    {
    	if (!x || cnt >= D) return;
    	for (int i = 1; i < D; ++i)
    		dp[x][i] *= 0.5 * (dp[son][i - 1] + 1);
    	update(fa[x], x, cnt + 1);
    }
    
    double ask(int x)
    {
    	double ans(0);
    	for (int i = 1; i < D; ++i)
    		ans += (double) i * (dp[x][i] - dp[x][i - 1]);
    	return ans;
    }
    
    int main() 
    {
    #ifndef ONLINE_JUDGE
        freopen("xhc.in", "r", stdin);
        freopen("xhc.out", "w", stdout);
    #endif
    	Q = read();
    	ncnt = 1;
    	fa[1] = 0;
    	fill(dp[1], dp[1] + D, 1);
    	while (Q--)
    	{
    		int op = read(), x = read();
    		if (op == 1)
    		{
    			fa[++ncnt] = x;
    			clear(fa[x], x, 1);
    			fill(dp[ncnt], dp[ncnt] + D, 1);
    			dp[x][0] *= 0.5;
    			update(x, ncnt, 0);
    		} else 
    		{
    			printf("%.7lf
    ", ask(x));
    		}
    	}
        return 0;
    }
    
  • 相关阅读:
    KMP算法
    cocos2d-x jsbinding 在线更新策略设计
    AS3动画效果公式,常用处理公式代码,基本运动公式,三角公式
    理解引导行为:路径跟踪
    适用于任何语言的编程策略
    Using中return对象
    js计算两个时间相差天数
    fastReport 绑定DataBand数据源后还是打印出一条数据
    无法处理文件 MainForm.resx,因为它位于 Internet 或受限区域中,或者文件上具有 Web 标记。要想处理这些文件,请删除 Web 标记
    附加数据库后登陆报错
  • 原文地址:https://www.cnblogs.com/cnyali-Tea/p/11439907.html
Copyright © 2011-2022 走看看