# bzoj 4034: 树上操作 线段树

## 题解:

ysf : 树链剖分大水题 !
lrd : 直接树剖不就好了嘛
gls : 这树剖不行吗 ?
lyc : ... ...

$1,2,3,-3,4,-4,-2,5,6,-6,-5,-1$

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(ll &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const ll maxn = 210010;
struct Edge{
ll to,next;
}G[maxn<<1];
inline void add(ll u,ll v){
G[++cnt].to = v;
}
#define v G[i].to
ll ind[maxn],dfs_clock,oud[maxn],idx[maxn];
void dfs(ll u,ll f){
ind[u] = ++ dfs_clock;
idx[dfs_clock] = u;
for(ll i = head[u];i;i=G[i].next){
if(v == f) continue;
dfs(v,u);
}
oud[u] = ++ dfs_clock;
idx[dfs_clock] = u;
}
#undef v
struct Node{
Node *ch[2];
ll val,lazy;
ll num1,num2;
void update(){
val = ch[0]->val + ch[1]->val;
num1 = ch[0]->num1 + ch[1]->num1;
num2 = ch[0]->num2 + ch[1]->num2;
}
}*null,mem[maxn<<2],*it,*root;
inline void init(){
it = mem;null = it++;
null->ch[0] = null->ch[1] = null;
null->val = null->lazy = null->num1 = null->num2 = 0;
root = null;
}
inline Node* newNode(){
Node *p = it++;p->ch[0] = p->ch[1] = null;
return p;
}
inline void pushdown(Node *p){
if(p == null || p->lazy == 0) return ;
if(p->ch[0] != null){
p->ch[0]->val += p->ch[0]->num1*p->lazy - p->ch[0]->num2*p->lazy;
p->ch[0]->lazy += p->lazy;
}
if(p->ch[1] != null){
p->ch[1]->val += p->ch[1]->num1*p->lazy - p->ch[1]->num2*p->lazy;
p->ch[1]->lazy += p->lazy;
}
p->lazy = 0;
}
inline void insert(Node* &p,ll l,ll r,ll pos,ll val,ll ty){
if(p == null) p = newNode();
if(l == r){
if(ty == 1) p->num1 = 1,p->num2 = 0;
else if(ty == -1) p->num1 = 0,p->num2 = 1;
p->val = p->num1*val - p->num2*val;
return ;
}
ll mid = l+r >> 1;
if(pos <= mid) insert(p->ch[0],l,mid,pos,val,ty);
else insert(p->ch[1],mid+1,r,pos,val,ty);
p->update();
}
inline void modify(Node *p,ll l,ll r,ll L,ll R,ll val){
if(L <= l &&r <= R){
p->lazy += val;
p->val += p->num1*val - p->num2*val;
return ;
}
pushdown(p);
ll mid = l+r >> 1;
if(L <= mid) modify(p->ch[0],l,mid,L,R,val);
if(R >  mid) modify(p->ch[1],mid+1,r,L,R,val);
p->update();
}
inline ll query(Node *p,ll l,ll r,ll L,ll R){
if(L <= l && r <= R) return p->val;
pushdown(p);ll mid = l+r >> 1;
if(R <= mid) return query(p->ch[0],l,mid,L,R);
if(L >  mid) return query(p->ch[1],mid+1,r,L,R);
return query(p->ch[0],l,mid,L,R) + query(p->ch[1],mid+1,r,L,R);
}
ll c[maxn];
int main(){init();
for(ll i=1,u,v;i<n;++i){
}dfs(1,1);
for(ll i=1;i<=n;++i){
insert(root,1,dfs_clock,ind[i],c[i],1);
insert(root,1,dfs_clock,oud[i],c[i],-1);
}
watch(root,1,dfs_clock);
ll op,x,a;
while(m--){
if(op == 1){
modify(root,1,dfs_clock,ind[x],ind[x],a);
modify(root,1,dfs_clock,oud[x],oud[x],a);
}else if(op == 2){