HDU-5759 Gardener Bo(线段树+分类讨论)
来源:互联网 发布:珠海知未科技有限公司 编辑:程序博客网 时间:2024/05/29 19:44
Gardener Bo
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 182 Accepted Submission(s): 67
Problem Description
Gardener Bo loves Trees.Now he asks you to help him take care of his lovely tree.
A rooted tree with root=1 is given.Every node on the tree has a valuewi .Letfa[u] be the father of u .
LetLCA(u,v) be the least common ancestor of u and v .The expression [condition] is 1 when condition is True,is 0 when condition is False.
Define
f(u)=∑i=1n∑j=in(wi+wj)∗[LCA(i,j)=u]
Now there areQ events happening.Each event has one of two types:
1 u x :pick out all v that satisfies v=u or fa[v]=u or fa[fa[v]]=u ,and add x to wv .
2 u :queryf(u)mod232 .
A rooted tree with root=1 is given.Every node on the tree has a value
Let
Define
Now there are
Input
There are several test cases.
The first line contains two integersn,Q .
The second line containsn−1 integers,i-th indicates fa[i+1] .
The third line containsn integers,the i-th indicates the initial wi .
FollowingQ lines each describes an event.
1≤n,Q≤3×105,|wi|,|x|<109
The first line contains two integers
The second line contains
The third line contains
Following
Output
For every event with type 2,you should print a number indicating the answer.
Sample Input
5 31 1 3 3-5 2 0 7 -61 5 22 32 210 51 2 3 3 1 2 6 2 2 -2 5 8 -6 0 -4 6 6 8 92 101 3 41 6 -22 92 4
题意:一棵树有n个节点,以1为根节点,每个节点有权值wi,定义f(u)为以u为根的子树中,LCA(u,v)=u的所有点对的权值和
有2种操作:
①选择点u,将u点以及它的子节点和孙子节点的权值都加上x
②查询f(u)
题解:具体的公式上面也给出了,最好对照的推一下公式。
其实对于1,2,3部分没必要用线段树维护,考虑到除了x都是常量,因此每次更新的时候只要打上标记:add[u]+=x,查询的时候加来就行。
对于第4部分,用树链剖分维护即可。每次更新点u,对于它的祖先中轻链上的点直接单点更新(轻链上的点的个数不超过logN个),然后由于一个节点只有1条重链,只要用树剖+线段树维护每个点对重链上的点的贡献即可。
#include<bits/stdc++.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;typedef long long LL;typedef unsigned int UI;const int MX = 3e5 + 5;const int inf = 0x3f3f3f3f;struct Edge{ int v,nxt;}E[MX*2];int head[MX],tot;int n,m;int fa[MX],son[MX],top[MX];int dfn[MX],out[MX],dfp;UI f[MX],c[MX],w[MX];UI sz[MX],cnt_son1[MX],cnt_son2[MX];UI add[MX],sum[MX<<2];void init(){ memset(add,0,sizeof(add)); memset(sum,0,sizeof(sum)); memset(head,-1,sizeof(head)); tot=dfp=0;}void add_edge(int u,int v){ E[tot].v=v; E[tot].nxt=head[u]; head[u]=tot++;}void dfs1(int u){ cnt_son1[u]=cnt_son2[u]=son[u]=c[u]=0; sz[u]=1; for(int i=head[u];~i;i=E[i].nxt){ int v=E[i].v; if(v==fa[u]) continue; dfs1(v); sz[u]+=sz[v]; cnt_son1[u]++; cnt_son2[u]+=cnt_son1[v]+1; c[u]+=sz[v]*cnt_son1[v]; if(sz[son[u]]<sz[v]) son[u]=v; } f[u]=w[u]*(sz[u]+1); for(int i=head[u];~i;i=E[i].nxt){ int v=E[i].v; if(v==fa[u]) continue; f[u]+=(sz[u]-sz[v])*w[v]; w[u]+=w[v]; }}void dfs2(int u,int t){ top[u]=t; dfn[u]=++dfp; if(son[u]) dfs2(son[u],t); for(int i=head[u];~i;i=E[i].nxt){ int v=E[i].v; if(v==son[u]||v==fa[u]) continue; dfs2(v,v); } out[u]=dfp;}void update(int x,UI val){ while(top[x]!=top[1]){ int v=top[x],u=fa[v]; f[u]+=(sz[u]-sz[v])*val; x=u; }}void Update(int p,UI val,int l,int r,int rt){ sum[rt]+=val; if(l==r) return; int m=(l+r)>>1; if(p<=m) Update(p,val,lson); else Update(p,val,rson);}UI query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r) return sum[rt]; int m=(l+r)>>1; UI ret=0; if(L<=m) ret+=query(L,R,lson); if(R>m) ret+=query(L,R,rson); return ret;}void solve(){ init(); for(int i=2;i<=n;i++) { scanf("%d",&fa[i]); add_edge(fa[i],i);add_edge(i,fa[i]); } for(int i=1;i<=n;i++) scanf("%u",&w[i]); dfs1(1); dfs2(1,1); while(m--){ int op,u; UI x; scanf("%d",&op); if(op==1){ scanf("%d%u",&u,&x); add[u]+=x; update(u,x*(1+cnt_son2[u])); Update(dfn[u],x*(1+cnt_son2[u]),1,n,1); } else{ scanf("%d",&u); UI ans=f[u]; ans+=add[u]*(2+sz[u]*cnt_son2[u]-c[u]); if(fa[u]) ans+=add[fa[u]]*(2+sz[u]*cnt_son1[u]); if(fa[fa[u]]) ans+=add[fa[fa[u]]]*(1+sz[u]); if(son[u]) { //son[u]存在表示u是重链上的 ans+=(sz[u]-sz[son[u]])*query(dfn[son[u]],out[son[u]],1,n,1); } printf("%u\n",ans); } }}int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) solve(); return 0;}
阅读全文
0 0
- 【HDU】5759 Gardener Bo【线段树+lca+分类讨论】
- HDU-5759 Gardener Bo(线段树+分类讨论)
- hdu 5759 2016 Multi-University Training Contest 3 Gardener Bo 解题报告
- BZOJ-1067 降雨量 线段树+分类讨论
- 【bzoj1067】【SCOI2007】【降雨量】【线段树+分类讨论】
- 【HDU】5957 Query on a graph【分类讨论+bfs序线段树】
- 【线段树】【分类讨论】水果姐逛水果街Ⅰ
- 【SCOI2007】【BZOJ1067】【codevs2439】降雨量,分类讨论の线段树
- Codeforces 799C Fountains【思维+分类讨论+线段树】
- 【HDU】5757 Product Bo【分情况讨论+队列】
- 线段树区间修改之双标记 【lazy两重标记并且分类讨论】
- BZOJ 1099([POI2007]树Drz-9次线段树&分类讨论+线段树与插入顺序维护2个参数)
- HDU 1061 Rightmost Digit(分类讨论)
- 【HDU】5296 Annoying problem【树链剖分+分类讨论】
- 【HDU】5786 Interval【分类讨论+容斥】
- HDU 4609 FFT+各种分类讨论
- hdu 3746 Cyclic Nacklace (KMP+分类讨论)
- hdu 6133 树状数组+分类讨论
- GET、POST区别
- Linux--进程复习
- Hdu 4093 ( Xavier is Learning to Count ) BZOJ2498 FFT+容斥原理
- jndi
- GitHub协同工作
- HDU-5759 Gardener Bo(线段树+分类讨论)
- 基于java的滤波器设计(IIR)
- Flutter实战一Flutter聊天应用(十四)
- 杯水风波
- 四、Eureka 的服务认证和集群
- eclipse Open Resource 过滤无效 maven项目
- linux中管理文件权限的管理
- Android中MultiAutoCompleteTextView和AutoCompleTextView
- 解决Android SDK下载和更新失败的方法