Propagating tree

Time Limit: 2000ms
Memory Limit: 262144KB

This problem will be judged on CodeForces. Original ID: 383C
64-bit integer IO format: %I64d      Java class name: (Any)

 
Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numbered from 1 to n, each node i having an initial value ai. The root of the tree is node 1.

This tree has a special property: when a value val is added to a value of node i, the value -val is added to values of all the children of node i. Note that when you add value -val to a child of node i, you also add -(-val) to all children of the child of node i and so on. Look an example explanation to understand better how it works.

This tree supports two types of queries:

  • "1 x val" — val is added to the value of node x;
  • "2 x" — print the current value of node x.

In order to help Iahub understand the tree better, you must answer m queries of the preceding type.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 200000). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 1000). Each of the next n–1 lines contains two integers viand ui (1 ≤ vi, ui ≤ n), meaning that there is an edge between nodes vi and ui.

Each of the next m lines contains a query in the format described above. It is guaranteed that the following constraints hold for all queries: 1 ≤ x ≤ n, 1 ≤ val ≤ 1000.

 

Output

For each query of type two (print the value of node x) you must print the answer to the query on a separate line. The queries must be answered in the order given in the input.

 

Sample Input

Input
5 5
1 2 1 1 2
1 2
1 3
2 4
2 5
1 2 3
1 1 2
2 1
2 2
2 4
Output
3
3
0

Hint

The values of the nodes are [1, 2, 1, 1, 2] at the beginning.

Then value 3 is added to node 2. It propagates and value -3 is added to it's sons, node 4 and node 5. Then it cannot propagate any more. So the values of the nodes are [1, 5, 1,  - 2,  - 1].

Then value 2 is added to node 1. It propagates and value -2 is added to it's sons, node 2 and node 3. From node 2 it propagates again, adding value 2 to it's sons, node 4 and node 5. Node 3 has no sons, so it cannot propagate from there. The values of the nodes are [3, 3,  - 1, 0, 1].

You can see all the definitions about the tree at the following link: http://en.wikipedia.org/wiki/Tree_(graph_theory)

 

Source

 
解题:此题有点坑,建两棵树一颗奇树,一颗偶树,奇数层节点奇树加,偶树减,偶数层节点,偶树加,奇树减。。。
 
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <cstdlib>
#include <string>
#include <set>
#include <stack>
#define LL long long
#define pii pair<int,int>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = ;
struct node {
int lt,rt,val;
};
struct arc{
int to,next;
arc(int x = ,int y = -){
to = x;
next = y;
}
};
node tree[][maxn<<];
arc e[maxn<<];
int head[maxn],lt[maxn],rt[maxn],val[maxn],d[maxn],idx,tot,n,m;
void add(int u,int v){
e[tot] = arc(v,head[u]);
head[u] = tot++;
}
void dfs(int u,int fa){
lt[u] = ++idx;
d[u] = d[fa]+;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa) continue;
dfs(e[i].to,u);
}
rt[u] = idx;
}
void build(int lt,int rt,int v) {
tree[][v].lt = tree[][v].lt = lt;
tree[][v].rt = tree[][v].rt = rt;
tree[][v].val = tree[][v].val = ;
if(lt == rt) return;
int mid = (lt + rt)>>;
build(lt,mid,v<<);
build(mid+,rt,v<<|);
}
void pushdown(int v,int o) {
if(tree[o][v].val) {
tree[o][v<<].val += tree[o][v].val;
tree[o][v<<|].val += tree[o][v].val;
tree[o][v].val = ;
}
}
void update(int lt,int rt,int v,int val,int o) {
if(tree[o][v].lt >= lt && tree[o][v].rt <= rt) {
tree[o][v].val += val;
return;
}
pushdown(v,o);
if(lt <= tree[o][v<<].rt) update(lt,rt,v<<,val,o);
if(rt >= tree[o][v<<|].lt) update(lt,rt,v<<|,val,o);
}
int query(int p,int v,int o){
if(tree[o][v].lt == tree[o][v].rt)
return tree[o][v].val;
pushdown(v,o);
if(p <= tree[o][v<<].rt) return query(p,v<<,o);
if(p >= tree[o][v<<|].lt) return query(p,v<<|,o);
}
int main() {
int u,v,op;
while(~scanf("%d %d",&n,&m)){
memset(head,-,sizeof(head));
idx = tot = ;
for(int i = ; i <= n; ++i)
scanf("%d",val+i);
for(int i = ; i < n; ++i){
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
build(,n,);
d[] = ;
dfs(,);
for(int i = ; i < m; ++i){
scanf("%d",&op);
if(op == ){
scanf("%d %d",&u,&v);
update(lt[u],rt[u],,v,d[u]&);
if(lt[u] < rt[u]) update(lt[u]+,rt[u],,-v,(~d[u])&);
}else{
scanf("%d",&u);
printf("%d\n",val[u]+query(lt[u],,d[u]&));
}
}
}
return ;
}

树状数组

 #include <bits/stdc++.h>
using namespace std;
const int maxn = ;
vector<int>g[maxn];
int c[][maxn],val[maxn],d[maxn],L[maxn],R[maxn],clk,n,m;
void dfs(int u,int fa,int dep){
d[u] = dep;
L[u] = ++clk;
for(int i = g[u].size()-; i >= ; --i){
if(g[u][i] == fa) continue;
dfs(g[u][i],u,dep+);
}
R[u] = clk;
}
void update(int cur,int i,int val){
while(i < maxn){
c[cur][i] += val;
i += i&-i;
}
}
int sum(int cur,int i,int ret = ){
while(i > ){
ret += c[cur][i];
i -= i&-i;
}
return ret;
}
int main(){
int u,v,op,x;
while(~scanf("%d%d",&n,&m)){
for(int i = ; i <= n; ++i){
g[i].clear();
scanf("%d",val+i);
}
for(int i = ; i < n; ++i){
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(,-,);
memset(c,,sizeof c);
while(m--){
scanf("%d%d",&op,&x);
if(op == ){
scanf("%d",&v);
update(d[x]&,L[x],v);
update(d[x]&,R[x]+,-v);
}else printf("%d\n",val[x] + sum(d[x]&,L[x]) - sum(~d[x]&,L[x]));
}
}
return ;
}

CodeForces 383C Propagating tree的更多相关文章

  1. codeforces 383C Propagating tree 线段树

    http://codeforces.com/problemset/problem/383/C 题目就是说,  给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val. ...

  2. Codeforces 383C . Propagating tree【树阵,dfs】

    标题效果: 有一棵树,有两种操作模式对本树:1:表示为(1 x val),在NOx加在节点上val,然后x每个节点加上儿子- val.给每个儿子一个儿子在一起-(- val),加到没有儿子为止.2:表 ...

  3. Codeforces 383C Propagating tree, 线段树, 黑白染色思想

    按深度染色,奇深度的点存反权值. #include <bits/stdc++.h> using namespace std; vector <]; ],a[],s[],vis[],i ...

  4. CodeForces 384E Propagating tree (线段树+dfs)

    题意:题意很简单么,给定n个点,m个询问的无向树(1为根),每个点的权值,有两种操作, 第一种:1 x v,表示把 x 结点加上v,然后把 x 的的子结点加上 -v,再把 x 的子结点的子结点加上 - ...

  5. AC日记——Propagating tree Codeforces 383c

    C. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  7. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  8. Codeforces Round #225 (Div. 2) E. Propagating tree dfs序+-线段树

    题目链接:点击传送 E. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  9. Problem - D - Codeforces Fix a Tree

    Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...

随机推荐

  1. HTML&CSS——网站注册页面

    1.表单标签 所有需要提交到服务器端的表单项必须使用<form></form>括起来! form 标签属性:  action,整个表单提交的位置(可以是一个页面,也可以是一个后 ...

  2. HDU 1175 连连看【BFS】

    题意:给出起点和终点的棋子,不能经过别的棋子,而且转弯的次数不能超过2次,问能否消除 和逃离迷宫一样,每个节点记录下来它的当前的方向和转弯的次数,再搜 注意特判起点的棋子和终点的棋子为0或者不一样的情 ...

  3. 在vue组件中style scoped中遇到的坑

    在uve组件中我们我们经常需要给style添加scoped来使得当前样式只作用于当前组件的节点.添加scoped之后,实际上vue在背后做的工作是将当前组件的节点添加一个像data-v-1233这样唯 ...

  4. java开发过程中几种常用算法

    排序算法 排序算法中包括:简单排序.高级排序 简单排序 简单排序常用的有:冒泡排序.选择排序.插入排序 冒泡排序代码如下: private static void bubbleSrot(int[] a ...

  5. h5实现 微信的授权登录

    本文重点 判断是不是微信环境 localstorage设置一个值 微信授权登录 获取一个时间戳 new Date().getTime() const wx = (function () { retur ...

  6. Linux 添加挂载硬盘(包含挂载大于2T以上硬盘)

    转自:http://blog.csdn.net/season_hangzhou/article/details/36423223 由于事先规划问题或者业务需求量激增,总会出现机器硬盘空间不够用的情况 ...

  7. FastDFS图片服务器搭建

    *FastDFS图片服务器搭建准备:1.需要libfastcommon安装包 选择最新稳定版(libfastcommon-1.0.36.tar.gz)2.需要FastDFS安装包 选择最新稳定版(fa ...

  8. 第五周-磁盘分区GPT、shell脚本练习、lvm详解

    1. 描述GPT是什么,应该怎么使用 Linux中磁盘分区分为MBR和GPT. MBR全称为Master Boot Record,为主引导记录,是传统的分区机制,应用于绝大多数使用的BIOS的PC设备 ...

  9. 【codeforces 95C】Volleyball

    [题目链接]:http://codeforces.com/problemset/problem/95/C [题意] 给你n个点,m条边; 每个点有一辆出租车; 可以到达离这个点距离不超过u的点,且在这 ...

  10. less12 函数

    less .x(1) { x:11 } .x(2) { y:22 } .x(@x:1) when (default()) {z:@x} //default()表示一直为真 body{ backgrou ...