正题

题目链接:http://www.51nod.com/Contest/Problem.html#contestProblemId=3957


题目大意

nnn个点的一棵树,第iii个节点上的动物有ai100\frac{a_i}{100}100ai​​的概率加入,每个加入的动物都会每秒向父节点移动。

对于第iii只动物,如果它到达一个节点时还没有其他动物比他早来过,那么它的权值加一。

现在对于每一只动物求它参加的话它的期望权值。

1≤n≤105,1≤ai≤1001\leq n\leq 10^5,1\leq a_i\leq 1001≤n≤105,1≤ai​≤100


解题思路

考虑一个动物xxx能拿到一个节点yyy的权值的条件,也就是yyy的子树中深度比xxx小的动物都不参赛的概率。

也就是对于一个动物xxx,动物zzz能对它产生影响首先要求depz<depxdep_z<dep_xdepz​<depx​,并且只会从LCA(x,z)LCA(x,z)LCA(x,z)处向上开始产生影响。

发现一个特点是从LCALCALCA处产生影响,这就和[LNOI2014]LCA很像了,我们对于会产生影响的zzz把它到根节点上的路径都修改了,然后直接询问xxx到根节点路径上的权值就好了。

至于depz<depxdep_z<dep_xdepz​<depx​这个条件我们把所有节点按照深度从小到大排序然后处理即可。

时间复杂度:O(nlog⁡2n)O(n\log^2 n)O(nlog2n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+10,P=998244353;
struct node{ll to,next;
}a[N<<1];
ll n,tot,cnt,inv100,fa[N],ls[N],c[N],p[N],ans[N];
ll siz[N],dep[N],son[N],top[N],seq[N],id[N];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
struct Seq_Tree{ll w[N<<2],lazy[N<<2];void Downdata(ll x){if(lazy[x]==1)return;w[x*2]=w[x*2]*lazy[x]%P;w[x*2+1]=w[x*2+1]*lazy[x]%P;lazy[x*2]=lazy[x*2]*lazy[x]%P;lazy[x*2+1]=lazy[x*2+1]*lazy[x]%P;lazy[x]=1;return;}void Build(ll x,ll L,ll R){lazy[x]=1;if(L==R){w[x]=1;return;}ll mid=(L+R)>>1;Build(x*2,L,mid);Build(x*2+1,mid+1,R);w[x]=w[x*2]+w[x*2+1];}void Change(ll x,ll L,ll R,ll l,ll r,ll val){if(L==l&&R==r){w[x]=w[x]*val%P;lazy[x]=lazy[x]*val%P;return;}ll mid=(L+R)>>1;Downdata(x);if(r<=mid)Change(x*2,L,mid,l,r,val);else if(l>mid)Change(x*2+1,mid+1,R,l,r,val);else Change(x*2,L,mid,l,mid,val),Change(x*2+1,mid+1,R,mid+1,r,val);w[x]=(w[x*2]+w[x*2+1])%P;}ll Ask(ll x,ll L,ll R,ll l,ll r){if(L==l&&R==r)return w[x];ll mid=(L+R)>>1;Downdata(x);if(r<=mid)return Ask(x*2,L,mid,l,r);if(l>mid)return Ask(x*2+1,mid+1,R,l,r);return (Ask(x*2,L,mid,l,mid)+Ask(x*2+1,mid+1,R,mid+1,r))%P;}
}T;
void dfs1(ll x){siz[x]=1;dep[x]=dep[fa[x]]+1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa[x])continue;fa[y]=x;dfs1(y);siz[x]+=siz[y];if(siz[y]>siz[son[x]])son[x]=y;}return;
}
void dfs2(ll x){id[x]=++cnt;seq[cnt]=x;if(son[x]){top[son[x]]=top[x];dfs2(son[x]);}for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==son[x]||y==fa[x]) continue;top[y]=y;dfs2(y);}
}
void Updata(ll x,ll val){while(x){T.Change(1,1,n,id[top[x]],id[x],val);x=fa[top[x]];}return;
}
ll Ask(ll x){ll ans=0;while(x){(ans+=T.Ask(1,1,n,id[top[x]],id[x]))%=P;x=fa[top[x]];}return ans;
}
bool cmp(ll x,ll y)
{return dep[x]<dep[y];}
signed main()
{inv100=power(100,P-2);scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&c[i]);p[i]=i;c[i]=(100-c[i])*inv100%P;}for(ll i=1;i<n;i++){ll x,y;scanf("%lld%lld",&x,&y);addl(x,y);addl(y,x);}dfs1(1);top[1]=1;dfs2(1);sort(p+1,p+1+n,cmp);T.Build(1,1,n);for(ll i=2,l=1;i<=n+1;i++){if(dep[p[i]]!=dep[p[i-1]]){ll r=i-1;for(ll j=l;j<=r;j++)ans[p[j]]=Ask(p[j]);for(ll j=l;j<=r;j++)Updata(p[j],c[p[j]]);l=i;}}for(ll i=1;i<=n;i++)printf("%lld\n",ans[i]);return 0;
}

51nod-动物与游戏【树链剖分,线段树】相关推荐

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  2. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  3. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  4. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  5. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  6. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  7. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. 图论 ---- C. Graph Transpositions(数据分阶段分层图最短路(二维) + 贪心)
  2. oracle创建序列seq起始值为1_oracle 重置序列从指定数字开始的方法详解
  3. python面向对象开发(类的属性-精讲
  4. 《从零开始学Swift》学习笔记(Day 7)——Swift 2.0中的print函数几种重载形式
  5. python基础教程攻略-python基础教程(一)
  6. 数据库基本概念 - 表、字段、sql语句
  7. Cambridge partner
  8. mysql备份工具Xtrabackup增量备份还原图解
  9. 找新朋友(欧拉函数)
  10. C++#define的用法(含特殊)
  11. 如何用ABAP代码读取SAP Business partner的附件数据
  12. Spring Boot 学习之,AOP统一处理请求日志
  13. sprintboot入门
  14. 解决git clone时报错fatal: HTTP request failed
  15. SpringBoot整合Sharding-JDBC实现水平分库分表之操作公共表
  16. Android tips(十)--允许模拟位置在Android M下的坑
  17. 基音提取之短时自相关法
  18. 电脑计算机c盘打不开怎么办,Win7系统电脑C盘打不开怎么办_Win7系统电脑C盘打不开的解决方法 - 系统家园...
  19. dva自定义组件及使用方法
  20. echarts饼状图的使用

热门文章

  1. 会计电算化的重要物质基础计算机和,湖北工业大学工程技术学院会计电算化管理办法...
  2. java 线程 插件_我的第一个Chrome插件:天气预报应用
  3. 四大金刚 数据结构_GIS技术在气象领域应用综述
  4. 系统同传软件_如何戴耳机录制自己的同传练习?
  5. c语言字符比较思路,C语言讲解思路资料
  6. ajax中迭代是什么意思,Ajax 局部刷新迭代器的内容
  7. iar 看时序_IAR 硬件仿真查看运行时间
  8. Java并发之volatile
  9. c++将字符串转换成 int 类型
  10. java中的循环结构_Java中的循环结构进阶