bzoj 4034: [HAOI2015]T2
来源:互联网 发布:网络加速器翻墙 编辑:程序博客网 时间:2024/04/29 00:16
Description
有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
Input
第一行包含两个整数 N, M 。表示点数和操作数。
接下来一行 N 个整数,表示树中节点的初始权值。
接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
Sample Input
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
Sample Output
6
9
13
9
13
HINT
对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不
会超过 10^6 。
Source
鸣谢bhiaibogf提供
一开始想用树链剖分,结果发现只需要维护dfs序就可以了
我用的是线段树维护。。没去想怎么用树状数组维护
首先dfs记录进入的时刻和弹出的时刻。进入权值为正,弹出为负
然后要查询路径的话直接查询1到x的权值和就可以了
单点修改就直接线段树上修改
子树就该即修改进入和弹出中间的那一段
每段维护正权值点和以及负权值点和。最后减一下就可以了
*记得开long long
#include<cstdio>using namespace std;struct line{ int s,t; int next;}a[200001];int head[100001];int edge;inline void add(int s,int t){ a[edge].next=head[s]; head[s]=edge; a[edge].s=s; a[edge].t=t;}int w[200001],b[200001];int ld[200001],rd[200001];bool v[200001];int tot;struct tree{ int l,r; long long s1,s2; long long x1,x2; long long tag;}tr[800001];inline void up(int p){ tr[p].s1=tr[p*2].s1+tr[p*2+1].s1; tr[p].x1=tr[p*2].x1+tr[p*2+1].x1; tr[p].s2=tr[p*2].s2+tr[p*2+1].s2; tr[p].x2=tr[p*2].x2+tr[p*2+1].x2;}inline void down(int p){ long long ll1,ll2,lr1,lr2; long long x=tr[p].tag; ll1=tr[p*2].x1; ll2=tr[p*2].x2; lr1=tr[p*2+1].x1; lr2=tr[p*2+1].x2; tr[p*2].s1+=ll1*x; tr[p*2].s2+=ll2*x; tr[p*2+1].s1+=lr1*x; tr[p*2+1].s2+=lr2*x; tr[p*2].tag+=x; tr[p*2+1].tag+=x; tr[p].tag=0;}inline void build(int p,int l,int r){ tr[p].l=l; tr[p].r=r; if(l!=r) { int mid=(l+r)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); up(p); } else { if(w[l]>0) { tr[p].s1=b[w[l]]; tr[p].x1=1; } else { tr[p].s2=b[-w[l]]; tr[p].x2=1; } }}inline void add1(int p,int l,int r,long long x){ if(l<=tr[p].l&&tr[p].r<=r) { if(tr[p].x1==1) tr[p].s1+=x; else tr[p].s2+=x; } else { down(p); int mid=(tr[p].l+tr[p].r)/2; if(l<=mid) add1(p*2,l,r,x); if(r>mid) add1(p*2+1,l,r,x); up(p); }}inline void add2(int p,int l,int r,long long x){ if(l<=tr[p].l&&tr[p].r<=r) { long long l1=tr[p].x1,l2=tr[p].x2; tr[p].s1+=x*l1; tr[p].s2+=x*l2; tr[p].tag+=x; } else { down(p); int mid=(tr[p].l+tr[p].r)/2; if(l<=mid) add2(p*2,l,r,x); if(r>mid) add2(p*2+1,l,r,x); up(p); }}tree nw;inline tree ask(int p,int l,int r){ if(l<=tr[p].l&&tr[p].r<=r) return tr[p]; else { down(p); int mid=(tr[p].l+tr[p].r)/2; tree ans1=nw,ans2=nw,ans=nw; bool flag1=false,flag2=false; if(l<=mid) { flag1=true; ans1=ask(p*2,l,r); } if(r>mid) { flag2=true; ans2=ask(p*2+1,l,r); } if(flag1) { if(flag2) { ans.s1=ans1.s1+ans2.s1; ans.s2=ans1.s2+ans2.s2; ans.x1=ans1.x1+ans2.x1; ans.x2=ans1.x2+ans2.x2; } else ans=ans1; } else ans=ans2; return ans; }}inline void dfs(int d){ tot++; ld[d]=tot; w[tot]=d; v[d]=true; int i; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(!v[t]) dfs(t); } tot++; rd[d]=tot; w[tot]=-d;}int main(){ int n,m; scanf("%d%d",&n,&m); int i; for(i=1;i<=n;i++) scanf("%d",&b[i]); int s,t; for(i=1;i<=n-1;i++) { scanf("%d%d",&s,&t); edge++; add(s,t); edge++; add(t,s); } dfs(1); build(1,1,tot); int x; for(i=1;i<=m;i++) { scanf("%d",&x); if(x==1) { scanf("%d%d",&s,&t); add1(1,ld[s],ld[s],t); add1(1,rd[s],rd[s],t); } else if(x==2) { scanf("%d%d",&s,&t); add2(1,ld[s],rd[s],t); } else { scanf("%d",&s); tree xt=ask(1,1,ld[s]); printf("%lld\n",xt.s1-xt.s2); } } return 0;}
0 0
- bzoj 4034: [HAOI2015]T2
- BZOJ 4034: [HAOI2015]T2
- BZOJ 4034 [HAOI2015]T2
- bzoj 4034 [HAOI2015]T2
- BZOJ 4034 [HAOI2015]T2 树链剖分
- [BZOJ 4034][HAOI2015]T2 [树链剖分]
- BZOJ 4034 [HAOI2015]T2 树链剖分+线段树
- bzoj 4034 [HAOI2015]T2 树链剖分+线段树
- BZOJ 4034: [HAOI2015]T2|线段树|树链剖分
- BZOJ-4034- [HAOI2015]T2-树链剖分+线段树
- BZOJ 4034 HAOI2015 T2 DFS序+线段树
- [dfs序 树状数组] BZOJ 4034 [HAOI2015]T2
- BZOJ 4034: [HAOI2015]T2(树链剖分,点权,线段树)
- BZOJ 4034([HAOI2015]T2-树链剖分对子树处理)
- 4034: [HAOI2015]T2 (树链剖分)
- 4034: [HAOI2015]T2
- 4034: [HAOI2015]T2 树链剖分+线段树
- BZOJ 4034 [HAOI2015]树上操作
- 河南省ACM程序设计 物资调度
- 【leetcode】Spiral Matrix II
- swing awt可视化操作插件WindowBuilder的安装
- 机房重构之组合查询
- 7
- bzoj 4034: [HAOI2015]T2
- 搭配nodejs mongodb开发环境
- 一个html5页面的思考
- Git操作-标签
- 和为S的连续正数序列
- Merge Sorted Array —— Leetcode
- 1.3 Factory Method(工厂方法) -- 对象创建型模式
- 未封装的JDBC(MySQL)数据库操作例子
- 【贪心算法,最小延迟调度】:poj***,***