# bzoj4034: [HAOI2015]T2

dfs序+线段树.

ps：val设成int，wa了无数发。。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn = 800000 + 10;
const int maxm = 800000 + 10;
const int maxk = 800000 + 10;

int g[maxn],v[maxm],next[maxm],eid;
int n,m,vid;
int a[maxm],b[maxm];
int in[maxn],out[maxn];
bool down[maxn];
//int id[maxn];

v[eid]=b; next[eid]=g[a]; g[a]=eid++;
v[eid]=a; next[eid]=g[b]; g[b]=eid++;
}

struct Segtree {
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)

int l[maxk],r[maxk];
int flag[maxk];

void push(int x) {
}

inline void update(int x) {
sumv[x]=sumv[lc(x)]+sumv[rc(x)];
}

void add(int x,int L,int R,LL val) {
if(R<l[x] || L>r[x]) return;
if(L<=l[x] && r[x]<=R) {
sumv[x]+=(flag[x]*val);
return;
}
push(x);
update(x);
}

LL query(int x,int L,int R) {
if(R<l[x] || L>r[x]) return 0;
if(L<=l[x] && r[x]<=R) return sumv[x];
push(x);
return (query(lc(x),L,R)+query(rc(x),L,R));
}

void build(int x,int L,int R) {
l[x]=L; r[x]=R;
if(L==R) {
sumv[x]=a[L];
if(down[L]) flag[x]=1;
else flag[x]=-1;
return;
}
int mid=(L+R)>>1;
build(lc(x),L,mid);
build(rc(x),mid+1,R);
update(x);
flag[x]=flag[lc(x)]+flag[rc(x)];
}

}seg;

void dfs(int u,int from) {
a[++vid]=b[u]; down[vid]=1;
in[u]=vid;
for(int i=g[u];~i;i=next[i]) if(v[i]!=from) dfs(v[i],u);
a[++vid]=-b[u];
out[u]=vid;    down[vid]=0;
}

int main() {
memset(g,-1,sizeof(g));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
for(int i=1,x,y;i<n;i++) {
scanf("%d%d",&x,&y);
}
dfs(1,0);
seg.build(1,1,(n<<1));
int p,x,a;
while(m--) {
scanf("%d",&p);
if(p==1) {
scanf("%d%d",&x,&a);
}
else if(p==2) {
scanf("%d%d",&x,&a);
}