zoukankan      html  css  js  c++  java
  • CodeForces

    http://codeforces.com/problemset/problem/696/B

    题目大意:

      这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不同的点的数量+1)
      每一次只有当子树中所有的点都已经游走过了再会向父亲走,走到每个儿子上的概率是相同的
      对于每个点,求他的权的期望

      (1 ≤ n ≤ 10^5)

    题解:

      

      首先我们发现,所有子树中所有的点的编号都一定比父亲要大

      而且子树中的大小关系和我们访问它的顺序有关

      如果对于一个节点u它的儿子为v(不只一个),那么我们知道访问顺序构成了一个全排列

      所以,我们知道:对于点v1,它在v2之前的概率是0.5(因为是全排列)、

      然后我们重新考虑这道题目:

      我们考虑一下,如果访问的时候v1先于v2被访问,那么对v2的编号的影响是什么?

      v2中的所有的编号都增加了v1.siz(),而这出现的概率是0.5

      那么我们就知道了,若v1先于v2被访问,那么E(v2) += 0.5*v1.siz();

      所以我们就有

      E(v) = E(u) + 1 + sigma{v1.siz()*0.5}
         = E(u) + 1 + 0.5(siz[u] - 1 siz[v])

      直接dfs可以O(n)解决!

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 inline void read(int &x){
     7     x=0;char ch;bool flag = false;
     8     while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
     9     while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    10 }
    11 inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    12 inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    13 const int maxn = 100010;
    14 struct Edge{
    15     int to,next;
    16 }G[maxn];
    17 int head[maxn],cnt;
    18 void add(int u,int v){
    19     G[++cnt].to = v;
    20     G[cnt].next = head[u];
    21     head[u] = cnt;
    22 }
    23 int siz[maxn];
    24 #define v G[i].to
    25 void dfss(int u){
    26     siz[u] = 1;
    27     for(int i=head[u];i;i=G[i].next){
    28         dfss(v);siz[u] += siz[v];
    29     }return;
    30 }double f[maxn];
    31 void dfs(int u){
    32     for(int i=head[u];i;i=G[i].next){
    33         f[v] = f[u] + 1.0 + (double)(siz[u] - 1 - siz[v])/2.0;
    34         dfs(v);
    35     }return;
    36 }
    37 #undef v
    38 int main(){
    39     int n;read(n);
    40     for(int i=2,x;i<=n;++i){
    41         read(x);add(x,i);
    42     }dfss(1);f[1] = 1.0;dfs(1);
    43     for(int i=1;i<=n;++i) printf("%.1lf ",f[i]);puts("");
    44     getchar();getchar();
    45     return 0;
    46 }
    47   
  • 相关阅读:
    某公司面试java试题之【二】,看看吧,说不定就是你将要做的题
    BAT面试上机题从3亿个ip中找出访问次数最多的IP详解
    Android 最流行的吸顶效果的实现及代码
    postgresql某进程占用cpu资源过高,降不下来
    媳妇要转java开发,我该怎么办?
    【原创】微信公众号电影网站域名被屏蔽完美解决方案!
    java如何对List集合中的元素进行排序(请收藏)
    【转】多语言的正则表达式,我们应该掌握
    【转】app之YdbOnline说明文档
    [敏捷开发实践](0) 开始
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6256101.html
Copyright © 2011-2022 走看看