modify2不会改了,其他应该都对了
# include <iostream>
# include <cstdio>
using namespace std;
const int maxn = 1e5 + 5;
int opt;
int n , m;
int x , y;
int w[maxn];
typedef long long ll;
typedef struct {
int x , y , next;
} Edge;
Edge edge[maxn];
typedef struct {
int l , r;
bool mark;
ll sum , lazy;
} Seg;
Seg tree[maxn * 4];
int E = 0 , elast[maxn];
void add(int x , int y) {
E ++;
edge[E].x = x;
edge[E].y = y;
edge[E].next = elast[x];
elast[x] = E;
}
int sta[maxn] , endd[maxn];
int siz[maxn];
int in[maxn] , ou[maxn] , dep[maxn] , cnt = 0 , tmp = 0;
void dfs_dfs(int x , int fa) {
in[x] = ++ tmp;
dep[x] = dep[fa] + 1;
siz[++ cnt] = x;
sta[x] = cnt;
for (int j = elast[x] ; j ; j = edge[j].next) {
int y = edge[j].y;
if (y != fa) {
dfs_dfs(y , x);
}
}
siz[++ cnt] = x;
endd[x] = cnt;
ou[x] = tmp;
}
bool ste[maxn];
void pushup(int p) {
tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
}
void buildtree(int p , int l , int r) {
tree[p].l = l;
tree[p].r = r;
tree[p].lazy = 0;
if (l == r) {
if (!ste[siz[l]]) {
tree[p].sum = w[siz[l]];
ste[siz[l]] = true;
return ;
} else {
tree[p].sum = -w[siz[l]];
return ;
}
} else {
int mid = l + r >> 1;
buildtree(p << 1 , l , mid);
buildtree(p << 1 | 1 , mid + 1 , r);
pushup(p);
}
}
void modify1(int p , int x , int d) {
if (tree[p].l == tree[p].r) {
tree[p].sum += d;
//cout << p << endl;
return ;
}
//cout << p << " " << tree[p].l << " " << tree[p].r << endl;
int mid = tree[p].l + tree[p].r >> 1;
//cout << "mid = " << mid << endl;
if (x <= mid) modify1(p << 1 , x , d);
else modify1(p << 1 | 1 , x , d);
pushup(p);
}
void pushdown(int p) {
auto &root = tree[p];
auto &left = tree[p << 1];
auto &right = tree[p << 1 | 1];
if (root.lazy) {
left.lazy += root.lazy;
left.sum += (ll)(left.r - left.l + 1) * (root.lazy);
right.lazy += root.lazy;
right.sum += (ll)(right.r - right.l + 1) * (root.lazy);
root.lazy = 0;
}
}
void modify2(int p , int l , int r , int d) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].sum += (ll)(tree[p].r - tree[p].l + 1) * d;
tree[p].lazy += d;
} else {
pushdown(p);
int mid = tree[p].l + tree[p].r >> 1;
if (l <= mid) modify2(p << 1 , l , r , d);
if (r > mid) modify2(p << 1 | 1 , l , r , d);
pushup(p);
}
}
ll query(int p , int l , int r) {
if (l <= tree[p].l && tree[p].r <= r) return tree[p].sum;
pushdown(p);
int mid = tree[p].l + tree[p].r >> 1;
ll ans = 0;
if (l <= mid) ans += query(p << 1 , l , r);
if (r > mid) ans += query(p << 1 | 1 , l , r);
return ans;
}
ll sum[maxn];
bool st[maxn];
int main() {
cin >> n >> m;
for (int i = 1 ; i <= n ; i ++) {
scanf("%d" , &w[i]);
}
for (int i = 1 ; i <= n - 1 ; i ++) {
scanf("%d%d" , &x , &y);
add(x , y);
}
dfs_dfs(1 , 0);
buildtree(1 , 1 , n << 1);/*
for (int i = 1 ; i <= 32 ; i ++) {
cout << i << " " << tree[i].l << " " << tree[i].r << " " << tree[i].sum << endl;
}*//*
for (int i = 1 ; i <= n ; i ++) {
cout << sta[i] << " ---> " << endd[i] << endl;
}*/
//cout << "sum = " << query(1 , 1 , n << 1) << endl;
for (int i = 1 ; i <= m ; i ++) {
scanf("%d" , &opt);
if (opt == 1) {
scanf("%d%d" , &x , &y);
modify1(1 , sta[x] , y);
modify1(1 , endd[x] , -y);
}
if (opt == 2) {
scanf("%d%d" , &x , &y);
modify2(1 , sta[x] , endd[x] , y);
}
if (opt == 3) {
scanf("%d" , &x);
printf("%lld\n" , query(1 , 1 , sta[x]));
}
}
return 0;
}