zoukankan      html  css  js  c++  java
  • Codeforces 500D. New Year Santa Network

    题目大意

    给你一颗有(n)个点的树(T),边上有边权。

    规定,(d(i,j))表示点i到点j路径上的边权之和。

    给你(q)次询问,每次询问格式为(i, j),表示将按输入顺序排序的第(i)条边边权修改为(j),并要求回答任取三个不同点(c_1,c_2,c_3),所带来的费用(d(c_1,c_2)+d(c_1,c_3) + d(c_2,c_3))的期望

    原题面

    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, bi, li (1 ≤ ai, bi ≤ n, ai ≠ 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 rj, wj (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.

    Examples

    Input

    Copy

    3
    2 3 5
    1 3 3
    5
    1 4
    2 2
    1 2
    2 1
    1 1

    Output

    14.0000000000
    12.0000000000
    8.0000000000
    6.0000000000
    4.0000000000

    Input

    Copy

    6
    1 5 3
    5 3 2
    6 1 7
    1 4 4
    5 2 3
    5
    1 2
    2 1
    3 5
    4 1
    5 2

    Output

    19.6000000000
    18.6000000000
    16.6000000000
    13.6000000000
    12.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).

    题解

    考虑任选三个点(a,b,c,)会发现答案是(a->b, a->c, b->c)所走过的边权之和的两倍

    考虑每一条边可能会被多少个三元组选中。相当于在割掉这条边的子树(T_1)(T_2)里选三个点的方案数

    期望除以(C(n, 3))即可

    注意会爆(long) (long),要(double)边乘边除才能过。虽然会降低精度,但(10^{-6})还(居)是(然)能过的。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <cmath>
    inline long long max(long long a, long long b){return a > b ? a : b;}
    inline long long min(long long a, long long b){return a < b ? a : b;}
    inline long long abs(long long x){return x < 0 ? -x : x;}
    inline void swap(long long &x, long long &y){long long tmp = x;x = y;y = tmp;}
    inline void read(long long &x)
    {
        x = 0;char ch = getchar(), c = ch;
        while(ch < '0' || ch > '9') c = ch, ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
        if(c == '-') x = -x;
    }
    const long long INF = 0x3f3f3f3f;
    const long long MAXN = 300000 + 10;
    struct Edge
    {
    	long long u, v, w, nxt, rank;
    	Edge(long long _u, long long _v, long long _w, long long _nxt, long long _rank){rank = _rank;u = _u;v = _v;nxt = _nxt;w = _w;}
    	Edge(){}
    }edge[MAXN << 1];
    long long head[MAXN], cnt = 1, pos[MAXN];
    inline void insert(long long a, long long b, long long c, long long d)
    {
    	edge[++ cnt] = Edge(a, b, c, head[a], d), head[a] = cnt;
    	edge[++ cnt] = Edge(b, a, c, head[b], d), head[b] = cnt;
    }
    long long n, q, size[MAXN];
    long long C(long long n, long long m)
    {
    	if(m == 1) return n;
    	else return n * (n - 1) >> 1;
    }
    void dfs(long long x, long long pre)
    {
    	size[x] = 1;
    	for(long long pos = head[x];pos;pos = edge[pos].nxt)
    	{
    		long long v = edge[pos].v;
    		if(v == pre) continue;
    		dfs(v, x);
    		::pos[edge[pos].rank] = pos;
    		size[x] += size[v];
    	}
    }
    double sum, mu;
    int main()
    {
    	read(n);mu = 1;
    	mu = n * (n - 1) / 2 * (n - 2) / 3; 
    	for(long long i = 1;i < n;++ i)
    	{
    		long long tmp1, tmp2, tmp3;
    		read(tmp1), read(tmp2), read(tmp3);
    		insert(tmp1, tmp2, tmp3, i);
    	}
    	dfs(1, -1);
    	for(long long i = 1;i < n;++ i)
    	{
    		long long p = pos[i];
    		sum += 2 * edge[p].w * 
    				   (C(size[edge[p].v], 1) * C(n - size[edge[p].v], 2) + 
    				    C(size[edge[p].v], 2) * C(n - size[edge[p].v], 1)) / mu;
    	}
    	read(q);
    	for(long long i = 1;i <= q;++ i)
    	{
    		long long tmp1, tmp2;
    		read(tmp1), read(tmp2);
    		long long p = pos[tmp1];
    		sum += 2 * (tmp2 - edge[p].w) * 
    				   (C(size[edge[p].v], 1) * C(n - size[edge[p].v], 2) + 
    				    C(size[edge[p].v], 2) * C(n - size[edge[p].v], 1)) / mu;
    		edge[p].w  = tmp2;
    		printf("%.10lf
    ", (double)sum);
    	}
        return 0;
    }
    
  • 相关阅读:
    CRM 客户线索 与 销售人员
    CRM X
    MySQL为Null导致的5大坑
    搞懂 macOS 上的主机名/hostname/ComputerName
    Node服务中如何写日志?
    Linux下 iptables 超详细教程和使用示例
    精读《Prisma 的使用》
    Redis夺命20问
    redis HyperLogLog的使用
    聊聊redis分布式锁的8大坑
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8541764.html
Copyright © 2011-2022 走看看