注:starch_tree 即点分树
#include <bits/stdc++.h>
using namespace std;
constexpr int MAXN = 3e5 + 5;
#define int long long
//* O(1) Get Distance
vector<int> G[MAXN];
int st[MAXN][25], cnt, pos[MAXN], dep[MAXN];
void dfs(int u, int pa) {
st[++cnt][0] = u;
pos[u] = cnt;
for (int v : G[u]) {
if (v == pa)
continue;
dep[v] = dep[u] + 1;
dfs(v, u);
st[++cnt][0] = u;
}
}
int cmp(int u, int v) {
if (dep[u] < dep[v])
return u;
else
return v;
}
void build_st() {
for (int j = 1; (1 << j) < cnt; j++)
for (int i = 1; i + (1 << j) <= cnt; i++)
st[i][j] = cmp(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
}
int ask_dis(int u, int v) {
int x = u, y = v;
u = pos[u];
v = pos[v];
if (u > v)
swap(u, v);
int len = __lg(v - u + 1);
int lca = cmp(st[u][len], st[v - (1 << len) + 1][len]);
return dep[x] + dep[y] - 2 * dep[lca];
}
//* Fenwick
struct Fenwick {
int n;
vector<long long> c;
void init(int _n) {
n = _n;
c.resize(n + 1);
}
int lowbit(int x) {
return x & (-x);
}
void update(int x, long long k) {
x++;
for (int i = x; i <= n; i += lowbit(i)) {
c[i] += k;
}
}
long long query(int x) {
x++;
long long res = 0;
if (x > n)
x = n;
for (int i = x; i >= 1; i -= lowbit(i))
res += c[i];
return res;
}
} fenwick[2][MAXN];
//* Starch Tree
constexpr int INF = 0x3f3f3f3f;
int mn, rt, sz[MAXN], all, fa[MAXN];
bool vis[MAXN];
void findrt(int u, int pa) {
int mx = 0;
sz[u] = 1;
for (int v : G[u]) {
if (v == pa || vis[v])
continue;
findrt(v, u);
sz[u] += sz[v];
mx = max(mx, sz[v]);
}
mx = max(mx, all - sz[u]);
if (mx < mn) {
mn = mx;
rt = u;
}
}
void build_starch_tree(int u) {
vis[u] = 1;
sz[u] = all + 1;
fenwick[0][u].init(sz[u]);
fenwick[1][u].init(sz[u]);
for (int v : G[u]) {
if (vis[v])
continue;
all = sz[v];
rt = 0;
mn = INF;
findrt(v, 0);
fa[rt] = u;
build_starch_tree(rt);
}
}
int query(int u, int v) {
int ans = fenwick[0][u].query(v);
for (int i = u; fa[i]; i = fa[i]) {
int dis = ask_dis(u, fa[i]);
if (v >= dis)
ans += fenwick[0][fa[i]].query(v - dis) - fenwick[1][i].query(v - dis);
}
return ans;
}
void modify(int u, int v) {
for (int i = u; i; i = fa[i]) {
fenwick[0][i].update(ask_dis(u, i), v);
}
for (int i = u; fa[i]; i = fa[i])
fenwick[1][i].update(ask_dis(u, fa[i]), v);
}
//* Main
int n, m, val[MAXN];
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> val[i];
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, -1);
build_st();
all = n;
mn = INF;
findrt(1, 0);
build_starch_tree(rt);
for (int i = 1; i <= n; i++)
modify(i, val[i]);
// cerr << "OK" << endl;
int lastans = 0;
while (m--) {
int opt, x, y;
cin >> opt >> x >> y;
x ^= lastans;
y ^= lastans;
if (opt == 0) {
cout << (lastans = query(x, y)) << endl;
} else {
modify(x, y - val[x]);
val[x] = y;
lastans = 0;
}
}
return 0;
}