CF 500D New Year Santa Network tree 期望 好题

New Year is coming in Tree World! In this world, as the name implies, there are n cities connected by n - 1 roads, and for any two distinct cities there always exists a path between them. The cities are numbered by integers from 1 to n, and the roads are numbered by integers from 1 to n - 1. Let‘s define d(u, v) as total length of roads on the path between city u and city v.

As an annual event, people in Tree World repairs exactly one road per year. As a result, the length of one road decreases. It is already known that in the i-th year, the length of the ri-th road is going to become wi, which is shorter than its length before. Assume that the current year is year 1.

Three Santas are planning to give presents annually to all the children in Tree World. In order to do that, they need some preparation, so they are going to choose three distinct cities c1, c2, c3 and make exactly one warehouse in each city. The k-th (1 ≤ k ≤ 3) Santa will take charge of the warehouse in city ck.

It is really boring for the three Santas to keep a warehouse alone. So, they decided to build an only-for-Santa network! The cost needed to build this network equals to d(c1, c2) + d(c2, c3) + d(c3, c1) dollars. Santas are too busy to find the best place, so they decided to choose c1, c2, c3 randomly uniformly over all triples of distinct numbers from 1 to n. Santas would like to know the expected value of the cost needed to build the network.

However, as mentioned, each year, the length of exactly one road decreases. So, the Santas want to calculate the expected after each length change. Help them to calculate the value.

Input

The first line contains an integer n (3 ≤ n ≤ 105) — the number of cities in Tree World.

Next n - 1 lines describe the roads. The i-th line of them (1 ≤ i ≤ n - 1) contains three space-separated integers aibili(1 ≤ ai, bi ≤ nai ≠ bi, 1 ≤ li ≤ 103), denoting that the i-th road connects cities ai and bi, and the length of i-th road is li.

The next line contains an integer q (1 ≤ q ≤ 105) — the number of road length changes.

Next q lines describe the length changes. The j-th line of them (1 ≤ j ≤ q) contains two space-separated integers rjwj(1 ≤ rj ≤ n - 1, 1 ≤ wj ≤ 103). It means that in the j-th repair, the length of the rj-th road becomes wj. It is guaranteed thatwj is smaller than the current length of the rj-th road. The same road can be repaired several times.

Output

Output q numbers. For each given change, print a line containing the expected cost needed to build the network in Tree World. The answer will be considered correct if its absolute and relative error doesn‘t exceed 10 - 6.

Sample test(s)

input

32 3 51 3 351 42 21 22 11 1

output

14.000000000012.00000000008.00000000006.00000000004.0000000000

input

61 5 35 3 26 1 71 4 45 2 351 22 13 54 15 2

output

19.600000000018.600000000016.600000000013.600000000012.6000000000

Note

Consider the first sample. There are 6 triples: (1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1). Because n = 3, the cost needed to build the network is always d(1, 2) + d(2, 3) + d(3, 1) for all the triples. So, the expected cost equals tod(1, 2) + d(2, 3) + d(3, 1).

题意:

一棵树,n个节点,编号为1~n,n-1条边按输入的顺序编号为1~n-1,给出n-1条边的权值

在树上任意选择3个点c1,c2,c3(不互相同),则连接这3个点的总花费:

dis(c1,c2)+dis(c1,c3)+dis(c2,c3)

注意:3个点的选择是随机的

接着q个改变,

每一个改变给出i w:把第i条边的权值改为w

每一个改变后,输出现在选择3个点总花费的期望。

思路:

一共有n*(n-1)*(n-2)种情况

在任意一种情况中,一条边要么没有被经过,要么被经过了2次

对于每一条边对期望的贡献=该边被经过的概率*该边的边长

而总期望=所有边的贡献之和

被经过的概率=1.0-没有被经过的概率

对于边e=(u,v)没有被经过,3个点要么都在u一侧,要么都在v一侧,根据siz数组可以轻易得到边没有被经过的概率

  1 #include<cstdio>
  2 #include<cstring>
  3
  4 using namespace std;
  5
  6 const int maxn=1e5+5;
  7 int siz[maxn];      //以节点i为根的子树的节点个数
  8 int dep[maxn];      //节点深度
  9 double pro[maxn];   //第i条边被经过的概率
 10 int e[maxn][3];
 11
 12 struct Edge
 13 {
 14     int to,next;
 15 };
 16 Edge edge[maxn<<1];
 17 int head[maxn];
 18 int tot;
 19
 20 void addedge(int u,int v)
 21 {
 22     edge[tot].to=v;
 23     edge[tot].next=head[u];
 24     head[u]=tot++;
 25 }
 26
 27 void init()
 28 {
 29     memset(head,-1,sizeof head);
 30     tot=1;
 31 }
 32
 33 //方便计算的函数
 34 double the_pro(double a,int n)
 35 {
 36     if(a<3)
 37         return 0.0;
 38     return (a*(a-1.0)*(a-2.0))/(n*(n-1.0)*(n-2.0));
 39 }
 40
 41 void swap(int &a,int &b)
 42 {
 43     a^=b;
 44     b^=a;
 45     a^=b;
 46 }
 47
 48 void solve(int );
 49 void dfs(int ,int );
 50
 51 int main()
 52 {
 53     init();
 54     int n;
 55     scanf("%d",&n);
 56     for(int i=1;i<n;i++)
 57     {
 58         scanf("%d %d %d",&e[i][0],&e[i][1],&e[i][2]);
 59         addedge(e[i][0],e[i][1]);
 60         addedge(e[i][1],e[i][0]);
 61     }
 62     solve(n);
 63     return 0;
 64 }
 65
 66 void solve(int n)
 67 {
 68     dep[1]=0;
 69     dfs(1,0);
 70
 71     for(int i=1;i<=n;i++)
 72     {
 73         if(dep[e[i][0]]>dep[e[i][1]])
 74             swap(e[i][0],e[i][1]);
 75     }
 76
 77     for(int i=1;i<n;i++)
 78     {
 79         pro[i]=1.0-the_pro(n-siz[e[i][1]],n)-the_pro(siz[e[i][1]],n);
 80         pro[i]*=2.0;
 81     }
 82     double ans=0.0;
 83     for(int i=1;i<n;i++)
 84     {
 85         ans+=pro[i]*e[i][2];
 86     }
 87     //ans表示最开始的期望
 88     int q;
 89     scanf("%d",&q);
 90     for(int j=1;j<=q;j++)
 91     {
 92         int i,w;
 93         scanf("%d %d",&i,&w);
 94         ans+=pro[i]*(w-e[i][2]);
 95         //边权改变,期望跟着改变
 96         printf("%.10f\n",ans);
 97         e[i][2]=w;
 98     }
 99     return ;
100 }
101
102 void dfs(int u,int pre)
103 {
104     siz[u]=1;
105     for(int i=head[u];~i;i=edge[i].next)
106     {
107         int v=edge[i].to;
108         if(v==pre)
109             continue;
110         dep[v]=dep[u]+1;
111         dfs(v,u);
112         siz[u]+=siz[v];
113     }
114 }

时间: 2024-08-05 07:06:05

CF 500D New Year Santa Network tree 期望 好题的相关文章

Codeforces 500D New Year Santa Network(树 + 计数)

D. New Year Santa Network time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output New Year is coming in Tree World! In this world, as the name implies, there are n cities connected by n - 1 roads,

codeforces 500D - New Year Santa Network (树形DP+组合数学)

题目地址:http://codeforces.com/contest/500/problem/D 这题是要先求出每条边出现的次数,然后除以总次数,这样期望就求出来了.先用树形DP求出每个边左右两端总共有多少个点,然后用组合数学公式就可以推出来了. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm>

cf500D New Year Santa Network

D. New Year Santa Network time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output New Year is coming in Tree World! In this world, as the name implies, there are n cities connected by n - 1 roads,

Good Bye 2014 D. New Year Santa Network

D. New Year Santa Network time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output New Year is coming in Tree World! In this world, as the name implies, there are n cities connected by n?-?1 roads,

CF280C Game on Tree (期望)

CF280C Game on Tree 期望的确是个玄学(原因可能是我太弱了) 还是不太会呢. 题意:期望多少次操作可以将树全部染黑 话说这个题求概率呢. 因为期望的线性性质,一棵树可以分解为多棵子树,而子树分解的最终状态就是点,所以我们可以计算每个点的期望操作次数再求和,这里的每个点的操作次数是指在这个点上操作. 因为在操作之前不能被染黑,并且必须要染黑. 所以期望次数为\(\sum_{i=1}^n1/dep[i]\) #include <iostream> #include <cst

CF 600E. Lomsat gelral(dsu on tree)

解题思路 \(dsu\) \(on\) \(tree\)的模板题.暴力而优雅的算法,轻儿子的信息暴力清空,重儿子的信息保留,时间复杂度\(O(nlogn)\) 代码 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<set> using namespace std; const int

HDU 4925 Apple Tree(模拟题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4925 解题报告:给你n*m的土地,现在对每一块土地有两种操作,最多只能在每块土地上进行两种操作,第一种是种苹果树操作,第二种是施肥操作,种苹果树操作可以使得该块地 长出一个苹果,施肥操作可以使得与这块土地相邻的土地的苹果产量变为原来的两倍,问可以得到的最多的苹果数量是多少? 例如一个4*4的土地,用1表示在该土地上做第一种操作,0表示在该土地上做第二种操作,可以得到最多苹果的操作如下: 0 1 0

Codeforces.280C.Game on Tree(期望)

题目链接 参考:浅谈期望的线性性(可加性) Codeforces 280C Game on Tree 概率dp 树上随机删子树 求删完次数的期望(这个的前半部分分析并没有看..) \(Description\) 给你一棵有\(n\)个白点的有根树,每次随机选择一个点,将它和它的子树中所有点染黑. 问期望操作多少次后所有点都被染黑? \(Solution\) 期望好玄啊..(好吧是我太弱) 因为概率具有可加性,一棵树可以分解为多棵子树,而子树分解的最终状态就是点,所以我们可以计算每个点的期望操作次

CF 504E Misha and LCP on Tree(树链剖分+后缀数组)

题目链接:http://codeforces.com/problemset/problem/504/E 题意:给出一棵树,每个结点上有一个字母.每个询问给出两个路径,问这两个路径的串的最长公共前缀. 思路:树链剖分,记录每条链的串,正反都记,组成一个大串.记录每条链对应的串在大串中的位置.然后对大串求后缀数组.最后询问就是在一些链上的查询. 树链剖分总是那么优秀.. const int N=600005; int next[N],node[N],head[N],e; void add(int u