题目链接

\(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常用模块-摘要算法(hashlib)

    Python常用模块-摘要算法(hashlib) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MD5算法参数详解 1.十六进制md5算法摘要 #!/usr/bin/env p ...

  2. Oozie 生成JMS消息并向 JMS Provider发送消息过程分析

    一,涉及到的工程 从官网下载源码,mvn 编译成 Eclipse工程文件:

  3. python 音乐下载演示源代码

    import requests import re api = 'http://music.taihe.com/search?' header = { 'User-Agent': 'Mozilla/5 ...

  4. BAT及各大互联网公司2014前端笔试面试题--Html,Css篇(昨天有个群友表示写的简单了点,然后我无情的把他的抄了一遍)

    某个群友 http://www.cnblogs.com/coco1s/   很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习前端基础 ...

  5. 浏览器存储:cookie

    Cookie是什么:cookie是指存储在用户本地终端上的数据,同时它是与具体的web页面或者站点相关的.Cookie数据会自动在web浏览器和web服务器之间传输,也就是说HTTP请求发送时,会把保 ...

  6. HDU 1308 What Day Is It?(模拟题)

    解题报告:输入一个年月日,让你求出那一天是星期几,但是做这题之前必须先了解一点历史.首先在1582年之前,判断是否是闰年的标准是只要能被四整除就是闰年, 然后在1752年9月2号的后的11天被抹去了, ...

  7. H5页面关于android软键盘弹出顶起底部元素的解决方案

    应用场景:用div在移动端页面设置一个底部工具栏,css的代码大概如下: .tool{ width: 100%; height: 60px; position: fixed; left: 0px; b ...

  8. OPENCV SVM介绍和自带例子

    依据机器学习算法如何学习数据可分为3类:有监督学习:从有标签的数据学习,得到模型参数,对测试数据正确分类:无监督学习:没有标签,计算机自己寻找输入数据可能的模型:强化学习(reinforcement ...

  9. 移动网络简介与RRC

    1.移动网络简介 1G:表示第一代移动通讯技术,以模拟技术为基础的蜂窝无线电话系统,如现在已经淘汰的模拟移动网.1G无线系统在设计上只能传输语音流量,并受到网络容量的限制. 2G:第二代手机通信技术规 ...

  10. docker 的简单操作

    一直说更博,但是一直在delay.... 最近一直用到docker,所以就总结一下吧! docker的介绍 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. ...