之前写的,忘了发上来了。
裸树剖。
/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100005;
int n, m, head[maxn], cnt, w[maxn], st[maxn], ed[maxn], size[maxn], top[maxn], son[maxn], clo, fa[maxn];
LL tr[maxn << 2], addv[maxn << 2];
struct _edge {
int v, next;
} g[maxn << 1];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline void add(int u, int v) {
g[cnt] = (_edge){v, head[u]};
head[u] = cnt++;
}
inline void dfs1(int x, int f) {
size[x] = 1; fa[x] = f;
for(int i = head[x]; ~i; i = g[i].next) if(g[i].v ^ f) {
dfs1(g[i].v, x);
size[x] += size[g[i].v];
if(size[g[i].v] > size[son[x]]) son[x] = g[i].v;
}
}
inline void dfs2(int x, int tp) {
st[x] = ++clo; top[x] = tp;
if(son[x]) dfs2(son[x], tp);
for(int i = head[x]; ~i; i = g[i].next) if(g[i].v ^ fa[x] && g[i].v ^ son[x])
dfs2(g[i].v, g[i].v);
ed[x] = clo;
}
inline void pushup(int p) {
tr[p] = tr[p << 1] + tr[p << 1 | 1];
}
inline void pushdown(int p, int l, int mid, int r) {
if(addv[p]) {
addv[p << 1] += addv[p]; addv[p << 1 | 1] += addv[p];
tr[p << 1] += addv[p] * (mid - l + 1); tr[p << 1 | 1] += addv[p] * (r - mid);
addv[p] = 0;
}
}
inline void add(int p, int l, int r, int x, int y, LL c) {
if(x <= l && r <= y) {
tr[p] += c * (r - l + 1); addv[p] += c;
return;
}
int mid = l + r >> 1;
pushdown(p, l, mid, r);
if(x <= mid) add(p << 1, l, mid, x, y, c);
if(y > mid) add(p << 1 | 1, mid + 1, r, x, y, c);
pushup(p);
}
inline LL query(int p, int l, int r, int x, int y) {
if(x <= l && r <= y) return tr[p];
int mid = l + r >> 1;
pushdown(p, l, mid, r);
LL ans = 0;
if(x <= mid) ans += query(p << 1, l, mid, x, y);
if(y > mid) ans += query(p << 1 | 1, mid + 1, r, x, y);
return ans;
}
inline LL query(int u) {
LL ans = 0;
for(; u; u = fa[top[u]]) ans += query(1, 1, n, st[top[u]], st[u]);
return ans;
}
int main() {
n = iread(); m = iread();
for(int i = 0; i <= n; i++) head[i] = -1; cnt = clo = 0;
for(int i = 1; i <= n; i++) w[i] = iread();
for(int i = 1; i < n; i++) {
int u = iread(), v = iread();
add(u, v); add(v, u);
}
dfs1(1, 0); dfs2(1, 1);
for(int i = 1; i <= n; i++) add(1, 1, n, st[i], st[i], w[i]);
while(m--) {
int opt = iread();
if(opt == 1) {
int u = iread(), c = iread();
add(1, 1, n, st[u], st[u], c);
}
else if(opt == 2) {
int u = iread(), c = iread();
add(1, 1, n, st[u], ed[u], c);
}
else if(opt == 3) {
int u = iread();
printf("%lld\n", query(u));
}
}
return 0;
}