bzoj 4034 [HAOI2015]树上操作
来源:互联网 发布:单身狗的嘲讽知乎 编辑:程序博客网 时间:2024/05/24 05:50
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 。
#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const int maxn = 1e5+10;int head[maxn];LL value[maxn];int N,M,edge_cnt;struct Edge{int to,next;}edge[maxn<<1];void ADD(int u,int v){edge[edge_cnt].to = v;edge[edge_cnt].next = head[u];head[u] = edge_cnt++;}int size[maxn],son[maxn],fa[maxn],deep[maxn];void dfs1(int now,int father,int Deep){size[now] = 1;fa[now] = father;deep[now] = Deep;son[now] = 0;for(int i = head[now]; ~i; i = edge[i].next){int v = edge[i].to;if(v != father){dfs1(v,now,Deep+1);size[now] += size[v];if(size[son[now]] < size[v])son[now] = v;}}}int id[maxn],Rank[maxn],top[maxn],tot,in[maxn],out[maxn];void dfs2(int now,int Top){top[now] = Top;id[now] = ++tot;in[now] = tot;Rank[id[now]] = now;if(son[now])dfs2(son[now],Top);for(int i = head[now]; ~i; i = edge[i].next){int v = edge[i].to;if(v!=fa[now] && v!=son[now]){dfs2(v,v);}}out[now] = tot;}struct node{LL sum,lazy;int l,r;};struct SGT{node tree[maxn<<2];void pushUp(int now){tree[now].sum = tree[now<<1].sum+tree[now<<1|1].sum;}void pushDown(int now){tree[now<<1].sum += (LL)(tree[now<<1].r-tree[now<<1].l+1)*tree[now].lazy;tree[now<<1|1].sum += (LL)(tree[now<<1|1].r-tree[now<<1|1].l+1)*tree[now].lazy;tree[now<<1].lazy += tree[now].lazy;tree[now<<1|1].lazy += tree[now].lazy;tree[now].lazy = 0;}void build(int now,int l,int r){tree[now].lazy = 0;tree[now].l = l;tree[now].r = r;if(l == r){tree[now].sum = value[Rank[l]];return;}int Mid = (l+r)>>1;build(now<<1,l,Mid);build(now<<1|1,Mid+1,r);pushUp(now);}void update(int now,int l,int r,LL val){if(l <= tree[now].l && tree[now].r <= r){tree[now].sum += (tree[now].r-tree[now].l+1)*val;tree[now].lazy += val;return;}pushDown(now);int Mid = (tree[now].l+tree[now].r)>>1;if(l <= Mid)update(now<<1,l,r,val);if(Mid < r)update(now<<1|1,l,r,val);pushUp(now);}LL query(int now,int l,int r){if(l <= tree[now].l && tree[now].r <= r){return tree[now].sum;}LL ans = 0;pushDown(now);int Mid = (tree[now].l+tree[now].r)>>1;if(l <= Mid)ans += query(now<<1,l,r);if(Mid < r)ans += query(now<<1|1,l,r);pushUp(now);return ans;}};SGT sgt;void work(int u){int tpu = top[u];LL ans = 0;while(tpu != 1){ans += sgt.query(1,id[top[u]],id[u]);u = fa[tpu];tpu = top[u];}ans += sgt.query(1,1 ,id[u]);printf("%lld\n",ans);}int main(){while(~scanf("%d %d",&N,&M)){memset(head,-1,sizeof(head));edge_cnt = tot = 0;for(int i = 1; i <= N; i++)scanf("%lld",&value[i]);int u,v;for(int i = 1; i < N; i++){scanf("%d %d",&u,&v);ADD(u,v);ADD(v,u);}dfs1(1,0,0);dfs2(1,1);sgt.build(1,1,N);int op,x;LL val;while(M--){scanf("%d %d",&op,&x);if(op == 1){scanf("%lld",&val);sgt.update(1,id[x],id[x],val);}else if(op == 2){scanf("%lld",&val);sgt.update(1,in[x],out[x],val);}elsework(x);}}return 0;}
阅读全文
0 0
- BZOJ 4034 [HAOI2015]树上操作
- bzoj 4034 [HAOI2015]树上操作
- 【BZOJ 4034】 [HAOI2015]树上操作
- BZOJ 4034: [HAOI2015]树上操作
- bzoj 4034 [HAOI2015]树上操作
- BZOJ 4034 [HAOI2015]树上操作
- bzoj 4034: [HAOI2015]树上操作 (树链剖分)
- 【BZOJ】4034 [HAOI2015]树上操作 树链剖分
- BZOJ 4034 [HAOI2015]树上操作 树链剖分
- BZOJ 4034 :[HAOI2015]树上操作 树链剖分裸题
- bzoj 4034: [HAOI2015]树上操作 树链剖分
- bzoj P4034 [HAOI2015]树上操作
- 4034: [HAOI2015]树上操作
- |BZOJ 4034|树链剖分|线段树|[HAOI2015]树上操作
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
- BZOJ[4034][HAOI2015]树上操作 树链剖分+线段树
- bzoj 4034: [HAOI2015]树上操作(线段树+dfs序)
- [树链剖分]bzoj 4034—— [HAOI2015]树上操作
- AngularJS 表单基本的验证功能
- Linux下Nginx安装
- leetcode 341. Flatten Nested List Iterator
- Mysql 支持存储表情
- 线程同步——内核对象(互斥、事件、信号量、可等待计时器)
- bzoj 4034 [HAOI2015]树上操作
- vmware上用kali破解wifi
- codeforces 834 C The Meaningless Game
- 小米5X 手机格式化照片原来这么简单就能找回,你知道吗
- 链表笔记
- PHP 计算两时间的时间差,倒计时
- Maximum Sequence
- PHPStorm 使用正则批量查询替换并自动转换大小写的方法
- 【杂记】万丈红尘一杯酒,千秋大业一壶茶