CodeForces-1046D Interstellar battle(期望)

探讨在一棵树状结构中,每个节点有特定消失概率的情况下,通过修改节点消失概率并询问形成的联通块数量,实现对星际帝国Bubbledom防御策略的优化。

D. Interstellar battle

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

In the intergalactic empire Bubbledom there are NN planets, of which some pairs are directly connected by two-way wormholes. There are N−1N−1 wormholes. The wormholes are of extreme religious importance in Bubbledom, a set of planets in Bubbledom consider themselves one intergalactic kingdom if and only if any two planets in the set can reach each other by traversing the wormholes. You are given that Bubbledom is one kingdom. In other words, the network of planets and wormholes is a tree.

However, Bubbledom is facing a powerful enemy also possessing teleportation technology. The enemy attacks every night, and the government of Bubbledom retakes all the planets during the day. In a single attack, the enemy attacks every planet of Bubbledom at once, but some planets are more resilient than others. Planets are number 0,1,…,N−10,1,…,N−1 and the planet ii will fall with probability pipi. Before every night (including the very first one), the government reinforces or weakens the defenses of a single planet.

The government of Bubbledom is interested in the following question: what is the expected number of intergalactic kingdoms Bubbledom will be split into, after a single enemy attack (before they get a chance to rebuild)? In other words, you need to print the expected number of connected components after every attack.

Input

The first line contains one integer number NN (1≤N≤1051≤N≤105) denoting the number of planets in Bubbledom (numbered from 00 to N−1N−1).

The next line contains NN different real numbers in the interval [0,1][0,1], specified with 2 digits after the decimal point, denoting the probabilities that the corresponding planet will fall.

The next N−1N−1 lines contain all the wormholes in Bubbledom, where a wormhole is specified by the two planets it connects.

The next line contains a positive integer QQ (1≤Q≤1051≤Q≤105), denoting the number of enemy attacks.

The next QQ lines each contain a non-negative integer and a real number from interval [0,1][0,1], denoting the planet the government of Bubbledom decided to reinforce or weaken, along with the new probability that the planet will fall.

Output

Output contains QQ numbers, each of which represents the expected number of kingdoms that are left after each enemy attack. Your answers will be considered correct if their absolute or relative error does not exceed 10−410−4.

Example

input

Copy

5
0.50 0.29 0.49 0.95 0.83
2 3
0 3
3 4
2 1
3
4 0.66
1 0.69
0 0.36

output

Copy

1.68040
1.48440
1.61740

题意:一棵n个节点的树,第i个节点消失的概率为P_i,每轮一次修改操作+询问,即将u消失的概率修改为r,然后询问这一轮会形成几个联通块(修改有后效性)。

题解:期望求贡献

我们先假设一开始没有任何边,那么联通块个数ans=n

因为第i个节点消失的概率为P_i,所以节点i的负贡献为-P_i

假设u,v之间有一条边,那么只要u,v有一个不消失,就会提供1点贡献

反过来如果u,v都不消失,那么负贡献就是(1-P_u)*(1-P_v)

所以我们只要维护一下每个点周围所有点的\sum(1-P_v)

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define per(i,a,b) for(int i=a-1;i>=(b);--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'<<endl
#define clr(a,b) memset(a,b,sizeof(a))
#define eps 1e-10
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef unsigned int ui;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int mod = 1e9 + 7;
const int MX = 2e5 + 5;

VI E[MX];
int f[MX];
double p[MX], t[MX], ans;
void dfs(int u, int pre) {
    f[u] = pre;
    ans -= p[u];
    for(auto v : E[u]) {
        if(v == pre) continue;
        t[u] += 1 - p[v];
        dfs(v, u);
    }
    ans -= t[u] * (1 - p[u]);
}

int main() {
#ifdef local
    freopen("in.txt", "r", stdin);
#endif // local
    int n; cin >> n;
    rep(i, 1, n + 1) scanf("%lf", &p[i]);
    rep(i, 1, n) {
        int u, v; scanf("%d%d", &u, &v);
        u++, v++;
        E[u].pb(v);
        E[v].pb(u);
    }
    ans = n;
    dfs(1, 0);
    int q; cin >> q;
    while(q--) {
        int u; double r;
        scanf("%d%lf", &u, &r); u++;
        //fuck(f[u]);
        ans += (1 - p[u]) * t[u] + p[u];
        if(f[u]) ans += (1 - p[u]) * (1 - p[f[u]]);
        t[f[u]] += (1 - r) - (1 - p[u]);
        ans -= (1 - r) * t[u] + r;
        if(f[u]) ans -= (1 - r) * (1 - p[f[u]]);
        p[u] = r;
        printf("%.6f\n", ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值