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, 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 ai,bili (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 integersrjwj (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 that wj 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 to d(1, 2) + d(2, 3) + d(3, 1).

这题赛中没做出来有点可惜呀(不然黄了)。题意是给出一棵带权树。

问你在树上任意选3个点 c1 , c2 ,c3 的 d(c1,c2) + d(c2,c3) + d(c1 ,c3 ) 的期望。

因为每一颗树上面的边都是桥。

只要计算每一条边在所有情况下[ C(3 , n ) ]使用的次数cnt便可以知道总路程d = sigma( cnt[i] *w[i] )

那么exp = d / C(3 ,n ) 。

q次询问更改边权就是减去之前的边期望, 加上新的边权求出来的期望 。

注意要用 , cnt[i]*w[i] / C(3 , n ) 处理好边, 即边期望。

若果先求出总路程再除C(3 , n )的话数据过大会溢出(挂大数据呀QAQ)。

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int>pii;
#define X first
#define Y second
const int N = 100010;

int n , cnt[N];
double W[N] , Cn3, res;

vector<pii>g[N];

int dfs( int u , int fa ){
    int tot = 0 ;
    for( int i = 0 ; i < g[u].size(); ++i ){
        int v = g[u][i].X , id = g[u][i].Y;
        if( v == fa ) continue ;
        cnt[id] = dfs( v , u );
        tot += cnt[id];
    }
    return tot + 1 ;
}

double cal( int id ){
    double a = cnt[id] , b = n - cnt[id];
    return 2.0*W[id]/Cn3*(a*(a-1)/2.0*b + b*(b-1)/2.0*a);
}

int main()
{
    int u , v ;
    cin >> n ;
    Cn3 = 1.0*n*(n-1)*(n-2)/6 , res = 0 ;
    for( int i = 1 ; i < n ; ++i ){
        scanf("%d%d%lf",&u,&v,&W[i]);
        g[u].push_back(pii(v,i));
        g[v].push_back(pii(u,i));
    }
    int m = dfs(1,0);
    for( int i = 1 ; i < n ; ++i ) res += cal(i);
    int q ; scanf("%d",&q);
    while(q--){
        int x ;double y ; scanf("%d%lf",&x,&y);
        res -= cal(x); W[x] = y ;res += cal(x);
        printf("%.9lf\n",res);
    }
}

时间: 2024-10-18 21:44:59

Codeforces 500D New Year Santa Network(树 + 计数)的相关文章

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>

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

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,

Codeforces 444C DZY Loves Colors(线段树)

题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是修改区间上l到r上面德值为x,2是询问l到r区间总的修改值. 解题思路:线段树模板题. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxn = 5*1e5; typedef long lo

CodeForces 706D Vasiliy&#39;s Multiset (字典树查询+贪心)

题意:最开始的时候有一个集合,集合里面只有一个元素0,现在有q次操作,操作分为3种: + x: 表示向集合中添加一个元素x - x:表示删除集合中值为x的一个元素 ? x:表示查询集合中与x异或的最大值为多少 析:这是一个字典树的应用,不过确实没看出来....主要思想是这样,先用10进制数,转成二进制数,记下每个结点的0,1的个数,这样增加和删除,就是对01的删除, 剩下的就是查询,那么尽量让0和1XOR是最大的,所以,对于给定数,我们要去尽量他的XOR数,如果找到就加上,找不到,就找下一个.这

Codeforces Round #261 (Div. 2) D 树状数组应用

看着题意:[1,i]中等于a[i]的个数要大于[,jn]中等于a[j]的个数 且i<j,求有多少对这样的(i,j)  ,i<j但是 i前面的合法个数 要大于j后面的 看起来很像逆序数的样子,所以很容易往树状数组想去,但是处理就看个人了,像我比赛的时候就处理得非常的麻烦,虽做出了但是花时间也多,经过杰哥的教育,其实正着塞进树状数组 反着来找就可以了,灰常的简单清晰明了,贴一发纪念我的搓比 int n; int aa[1000000 + 55]; int bb[1000000 + 55]; int

Codeforces 29D Ant on the Tree 树的遍历 dfs序

题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问. 思路: 给每个节点加一个优先级. 把最后一个叶子节点到父节点的路径上的点优先级改为1 把倒数第二个叶子节点到父节点的路径上的点优先级改为2 如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可 对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解. #include <cstdio> #

Codeforces 219D. Choosing Capital for Treeland (树dp)

题目链接:http://codeforces.com/contest/219/problem/D 树dp 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio&