题目链接

\(Description\)

有一棵树。Limak可以攻击树上的某棵子树,然后这棵子树上的每条边有\(\frac{1}{2}\)的概率消失。定义 若攻击以\(x\)为根的子树,高度\(ht(x)\)为\(x\)子树剩余点(与x连通)的最大深度。共\(q\)次操作,两种:
\(1\ x\).新建一个节点,其父节点为\(x\)。
\(2\ x\).询问若攻击以\(x\)为根的子树,\(x\)子树的期望高度。
\(q\leq 5\times10^5\)。允许有一定精度误差。

\(Solution\)

首先我们不需要考虑很大的高度\(h\),假如\(h=100\),同时存在\(100\)条边的概率非常小。先假设需考虑的最大高度\(MAX\_H=60\)。
对于询问,只要\(x\)有一个子树的高度为\(h\)且其它子树高度不超过\(h\),就可以用\(p*h\)更新答案。
so记\(f[x][h]\)表示以\(x\)为根,\(ht(x)\leq h\)的概率。则答案为\(\sum_{h=1}^{MAX\_H}h\times(f[x][h]-f[x][h-1])\)。
对于新建节点,沿着\(fa\)一直更新最多\(MAX\_H\)次。
\(f[x][h]\)自然是从\(f[son_x][h-1]\)转移。每个子节点\(v\)有两种情况,一是存在边,对\(f[x][h]\)贡献\(\frac{1}{2}\times f[v][h-1]\);二是不存在该边,概率为\(\frac{1}{2}\)。
更新时当然不能\(2^n\)枚举子节点。类似多项式,把\(n\)项乘在一起,即\[f[x][h]=\prod_{v=son_x}(\frac{1}{2}+\frac{1}{2}f[v][h-1])\]
所以更新的时候把原来的项除掉再乘上新的项就可以了。

对于\(MAX\_H\)的取值,你可能会认为\(30\)就足够了,因为\(\frac{1}{2^{30}}\)已经足够小。事实上,考虑一个菊花图,从根节点延伸出\(\frac{n}{31}\)条路径,且每条路径长度为\(31\)。那么以\(1\)为根树深为\(31\)的概率为:\[1-(1-\frac{1}{2^{31}})^{\frac{n}{31}}\]
这是大于\(10^{-6}\)的。
http://www.wolframalpha.com/input/?i=1+-+(1-(1%2F2)%5Ed)%5E(N%2Fd)+for+N+%3D+500000+and+d+%3D+31

复杂度\(O(q*MAX\_H)\)

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAX_H 60
const int N=5e5+5;

int n,fa[N];
double f[N][MAX_H];

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}

int main()
{
    n=1;
    for(int i=0; i<MAX_H; ++i) f[1][i]=1;
    for(int Q=read(),x; Q--; )
    {
        if(read()==1)
        {
            fa[++n]=x=read();
            for(int i=0; i<MAX_H; ++i) f[n][i]=1;
            double tmp1=f[x][0],tmp2;
            f[x][0]*=0.5;//深度还是不超过1啊
            for(int Fa=fa[x],i=1; Fa&&i<MAX_H; Fa=fa[x=Fa],++i)
            {
                tmp2=f[Fa][i];
                f[Fa][i] /= 0.5 + 0.5*tmp1;
                f[Fa][i] *= 0.5 + 0.5*f[x][i-1];
                tmp1=tmp2;
            }
        }
        else
        {
            x=read(); double ans=0;
            for(int i=1; i<MAX_H; ++i) ans+=(f[x][i]-f[x][i-1])*i;
            printf("%.10lf\n",ans);
        }
    }
    return 0;
}

Codeforces.643E.Bear and Destroying Subtrees(DP 期望)的更多相关文章

  1. CF643E. Bear and Destroying Subtrees 期望dp

    题目链接 CF643E. Bear and Destroying Subtrees 题解 dp[i][j]表示以i为根的子树中,树高小于等于j的概率 转移就是dp[i][j] = 0.5 + 0.5 ...

  2. CF 643 E. Bear and Destroying Subtrees

    E. Bear and Destroying Subtrees http://codeforces.com/problemset/problem/643/E 题意: Q个操作. 加点,在原来的树上加一 ...

  3. 笔记-CF643E Bear and Destroying Subtrees

    CF643E Bear and Destroying Subtrees 设 \(f_{i,j}\) 表示节点 \(i\) 的子树深度为 \(\le j\) 的概率,\(ch_i\) 表示 \(i\) ...

  4. [CF643E]Bear and Destroying Subtrees(期望,忽略误差)

    Description: ​ 给你一棵初始只有根为1的树 ​ 两种操作 ​ 1 x 表示加入一个新点以 x为父亲 ​ 2 x 表示以 x 为根的子树期望最深深度 ​ 每条边都有 \(\frac{1}{ ...

  5. CF643E Bear and Destroying Subtrees

    题解 我们可以先写出\(dp\)式来. 设\(dp[u][i]\)表示以\(u\)为根的子树深度不超过\(i-1\)的概率 \(dp[u][i]=\prod (dp[v][i-1]+1)*\frac{ ...

  6. [cf674E]Bear and Destroying Subtrees

    令$f_{i,j}$表示以$i$为根的子树中,深度小于等于$j$的概率,那么$ans_{i}=\sum_{j=1}^{dep}(f_{i,j}-f_{i,j-1})j$ 大约来估计一下$f_{i,j} ...

  7. Codeforces 771E Bear and Rectangle Strips DP

    题意: 一个由大写字母组成的长度为\(n(n \leq 75)\)的字符串,每次操作可以交换相邻位置的两个字母,求最少操作多少次使字符串中不出现子串VK 分析: VK之外的字母具体是什么,我们并不关心 ...

  8. Codeforces 385C Bear and Prime Numbers

    题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...

  9. Codeforces 385B Bear and Strings

    题目链接:Codeforces 385B Bear and Strings 记录下每一个bear的起始位置和终止位置,然后扫一遍记录下来的结构体数组,过程中用一个变量记录上一个扫过的位置,用来去重. ...

随机推荐

  1. python创建与遍历List二维列表

    python创建与遍历List二维列表 觉得有用的话,欢迎一起讨论相互学习~Follow Me python 创建List二维列表 lists = [[] for i in range(3)] # 创 ...

  2. postman提取接口的返回值及动态设置变量(一)

    一.提取接口返回值   1.当返回值是返回JSON时 let json = JSON.parse(responseBody); // responseBody是包含整个返回内容的字符串 let foo ...

  3. LINQ 查询

    概述 事实上,对于LINQ to Objects来说,就是通过为IEnumerable<T>接口定义了一组约50个扩展方式来实现的. Lambda表达式(拉姆达表达式,Lambda Exp ...

  4. Javascript摸拟自由落体与上抛运动 说明!

    JavaScript 代码 //**************************************** //名称:Javascript摸拟自由落体与上抛运动! //作者:Gloot //邮箱 ...

  5. 20155217 2016-2017-2 《Java程序设计》第5周学习总结

    20155217 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 java中所有错误都会被包装为对象,可以尝试(try)执行程序并捕捉(catch)代 ...

  6. 关于gb2312编码和utf8码的一个问题

    ANSI(注意拼写不是ASCII)并不是“一种”编码,而是“多种”编码的统称.在简体中文Windows上,ANSI指GBK编码:在繁体中文Windows上,ANSI指Big5编码:在英文Windows ...

  7. 数链剖分(Housewife Wind )

     题目链接:https://vjudge.net/contest/279350#problem/B 题目大意:给你n,q,s.n指的是有n个点,q代表有q次询问,s代表的是起点.然后接下来会有n-1条 ...

  8. word技巧

    1.插入注解(脚注和尾注) 2.复制的图片显示不全怎么办? 横向显示,或者图片另存为然后保存为PPT 3.word修订标记的添加和删除(最终版) 4.word中表格样式调整 5.修改标题的样式和标题的 ...

  9. python2.7中MySQLdb的安装与使用详解

    Python2.7中MySQLdb的使用 import MySQLdb #1.建立连接 connect = MySQLdb.connect( '127.0.0.1', #数据库地址 'root', # ...

  10. arm GIC介绍之四【转】

    转自:https://blog.csdn.net/sunsissy/article/details/73882718 GIC是ARM体系中重要的组件,在认识到GIC的组成和功能之后,了解到IRQ的大致 ...