zoukankan      html  css  js  c++  java
  • Codeforces 1045D Interstellar battle 概率期望

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1045D.html

    题目传送门 - CF1045D

    题意

      给定一棵有 $n$ 个节点的树,第 $i$ 个节点有 $p_i$ 的概率消失。有 $q$ 次操作,每次操作修改一个节点消失的概率,请你在每一次操作之后输出树的期望连通块个数。

      $n,qleq 10^5$

    题解

      首先我们考虑如何求解不操作的情况。

      考虑期望的线性性,我们统计每一个节点对答案的贡献。

      首先,假装每一个节点都是一个连通块。

      对于节点 x ,如果他消失了,那么连通块个数 -1,由于他消失的概率是 $p_x$ ,他对期望的贡献为 $p_i$ 。

      对于无序数对 $(x,y)$ ,如果 x 和 y 有边连接,那么,当且仅当他们都存在,才会对连通块个数产生贡献,所以它对期望的贡献为 $(1-p_x)(1-p_y)$ 。

      完成了这个问题之后,修改操作也变得简单了。

      首先给树定根。然后,只需要对于每一个节点 x 维护一个 vson[x] 代表其所有儿子的 $(1-p_y)$ 之和。修改操作就变的简单了。

      时间复杂度 $O(n)$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=100005;
    int n,Q,fa[N];
    double v[N],vson[N],ans;
    vector <int> e[N];
    void solve(int x,int pre){
    	ans-=1.0-v[x];
    	fa[x]=pre,vson[x]=0;
    	for (auto y : e[x])
    		if (y!=pre){
    			ans-=v[x]*v[y];
    			vson[x]+=v[y];
    			solve(y,x);
    		}	
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		e[i].clear();
    	v[0]=0;
    	for (int i=1;i<=n;i++)
    		scanf("%lf",&v[i]),v[i]=1.0-v[i];
    	for (int i=1,a,b;i<n;i++){
    		scanf("%d%d",&a,&b),a++,b++;
    		e[a].push_back(b);
    		e[b].push_back(a);
    	}
    	ans=n;
    	solve(1,0);
    	scanf("%d",&Q);
    	while (Q--){
    		int x;
    		double y;
    		scanf("%d%lf",&x,&y),x++;
    		ans+=v[fa[x]]*vson[fa[x]]+v[x]*vson[x]+1.0-v[x];
    		vson[fa[x]]-=v[x];
    		v[x]=1.0-y;
    		vson[fa[x]]+=v[x];
    		ans-=v[fa[x]]*vson[fa[x]]+v[x]*vson[x]+1.0-v[x];
    		printf("%.6lf
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Python编程笔记二进制、字符编码、数据类型
    Python之路Python内置函数、zip()、max()、min()
    替换RTXLogo插件说明
    RTX修改标题logo方法
    RTX和谐说明
    RTX数据表分析
    RTX系统整合记录
    HiMall 3接口鉴权参考
    第三方系统接入
    学习记录
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/CF1045D.html
Copyright © 2011-2022 走看看