过样例就行,我自己进行后续优化
# 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;
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 eskkk[maxn];
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) {
tmp ++;
dep[x] = dep[fa] + 1;
siz[++ cnt] = x;
sta[x] = cnt;
eskkk[tmp] = 1;
for (int j = elast[x] ; j ; j = edge[j].next) {
int y = edge[j].y;
if (y != fa) {
dfs_dfs(y , x);
}
}
tmp ++;
eskkk[tmp] = -1;
siz[++ cnt] = x;
endd[x] = cnt;
}
int Cnt = 0;
void dfs(int x , int fa) {
in[x] = ++ Cnt;
for (int j = elast[x] ; j ; j = edge[j].next) {
int y = edge[j].y;
if (y != fa) dfs(y , x);
}
ou[x] = ++ Cnt;
}
bool ste[maxn];
int num[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]];
//cout << p << " " << tree[p].sum << endl;
ste[siz[l]] = true;
return ;
} else {
tree[p].sum = -w[siz[l]];
//cout << p << " " << tree[p].sum << endl;
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) {
tree[p].sum += d;
if (tree[p].l == tree[p].r) {
return ;
}
int mid = tree[p].l + tree[p].r >> 1;
if (x <= mid) modify1(p << 1 , x , d);
else modify1(p << 1 | 1 , x , d);
}
void pushdown(int p , int mid , int l , int r) {
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)(num[mid] - num[l - 1]) * (root.lazy);
right.lazy += root.lazy;
right.sum += (ll)(num[r] - num[mid]) * (root.lazy);
root.lazy = 0;
}
}
void modify2(int p , int x , int y , int l , int r , int d) {
if (l <= tree[p].l && tree[p].r <= r) {
tree[p].sum += (ll)(num[r] - num[l - 1]) * d;
//cout << p << " " << r << " " << l << " " << (num[r] - num[l - 1]) * d << endl;
tree[p].lazy += d;
return ;
} else {
int mid = (tree[p].l + tree[p].r) >> 1;
//cout << p << mid << l << r << endl;
pushdown(p , mid , l , r);
if (l <= mid) modify2(p << 1 , x , mid , l , r , d);
if (r > mid) modify2(p << 1 | 1 , mid + 1 , y , 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;
}
int mid = (tree[p].l + tree[p].r) >> 1;
pushdown(p , mid , l , r);
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);
dfs(1 , 0);
for (int i = 1 ; i <= tmp ; i ++) {
num[i] = num[i - 1] + eskkk[i];
//cout << num[i] << " ";
}
//cout << endl;
/*
for (int i = 1 ; i <= n ; i ++) {
cout << in[i] << " " << ou[i] << endl;
}*/
buildtree(1 , 1 , n << 1);
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 , 1 , n << 1 , in[x] , ou[x] , y);
//cout << in[x] << " " << ou[x] << endl;
/*
for (int i = 1 ; i <= 32 ; i ++) {
if (tree[i].l == tree[i].r) {
printf("%d %d %d %d\n" , i , tree[i].l , tree[i].r , tree[i].sum);
}
}*/
}
if (opt == 3) {
scanf("%d" , &x);
printf("%lld\n" , query(1 , 1 , sta[x]));
}
}
return 0;
}