RT。
#include "bits/stdc++.h"
using namespace std;
const int Len = 1e5 + 5 , Inf = 1e9;
int n,q,a[Len],head[Len],cnt,dfa[Len],dp[21][Len],dep[Len],mx[Len],siz[Len],S,rt,dis[Len],vis[Len];
int rtt[Len][2];
inline int read() {
char ch = getchar();
int x = 0, f = 1;
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void write(int x) {
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
struct Seg
{
int tot,sum[Len * 60],lc[Len * 60],rc[Len * 60];
inline void push_up(int p){sum[p] = sum[lc[p]] + sum[rc[p]];}
void update(int &p,int l,int r,int idx,int w)
{
if(!p) p = ++ tot;
if(l == r){sum[p] += w;return;}
int mid = (l + r) >> 1;
if(idx <= mid) update(lc[p] , l , mid , idx , w);
else update(rc[p] , mid + 1 , r , idx , w);
push_up(p);
}
int query(int p,int l,int r,int nl,int nr)
{
if(!p) return 0;
if(nl <= l && nr >= r) return sum[p];
int mid = (l + r) >> 1 , res = 0;
if(nl <= mid) res += query(lc[p] , l , mid , nl , nr);
if(nr > mid) res += query(rc[p] , mid + 1 , r , nl , nr);
return res;
}
}S1;
struct node
{
int next,to;
}edge[Len << 1];
inline void add(int from,int to)
{
edge[++ cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt;
}
void dfs(int x,int f)
{
dp[0][x] = f;
dep[x] = dep[f] + 1;
for(int i = 1 ; (1 << i) <= dep[x] ; i ++) dp[i][x] = dp[i - 1][dp[i - 1][x]];
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(to == f) continue;
dfs(to , x);
}
}
inline int FLCA(int x,int y)
{
if(dep[x] < dep[y]) swap(x , y);
for(int i = 20 ; i >= 0 ; i --) if(dep[dp[i][x]] >= dep[y]) x = dp[i][x];
if(x == y) return x;
for(int i = 20 ; i >= 0 ; i --) if(dp[i][x] != dp[i][y]) x = dp[i][x] , y = dp[i][y];
return dp[0][x];
}
inline int getdis(int x,int y){return dep[x] + dep[y] - dep[FLCA(x , y)] * 2;}
void resiz(int x,int f)
{
siz[x] = 1;
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(to == f || vis[to]) continue;
resiz(to , x);
siz[x] += siz[to];
}
}
void getrt(int x,int f)
{
mx[x] = 0 , siz[x] = 1;
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(to == f || vis[to]) continue;
getrt(to , x);
siz[x] += siz[to];
mx[x] = max(mx[x] , siz[to]);
}
mx[x] = max(mx[x] , S - siz[x]);
if(mx[x] < mx[rt]) rt = x;
}
void Build(int x)
{
vis[x] = 1;
for(int e = head[x] ; e ; e = edge[e].next)
{
int to = edge[e].to;
if(vis[to]) continue;
S = siz[to] , mx[rt = 0] = Inf;
getrt(to , 0);resiz(rt , 0);
dfa[rt] = x , Build(rt);
}
}
inline void upd(int x,int v)
{
int now = x;
while(now)
{
S1.update(rtt[now][0] , 0 , n - 1 , getdis(x , now) , v);
if(dfa[now]) S1.update(rtt[now][1] , 0 , n - 1 , getdis(dfa[now] , x) , v);
now = dfa[now];
}
}
inline int qry(int x,int k)
{
int now = x , pre = 0 , res = 0;
while(now)
{
if(getdis(now , x) <= k)
{
int w1 = S1.query(rtt[now][0] , 0 , n - 1 , 0 , k - getdis(x , now)) , w2 = 0;
if(pre) w2 = -S1.query(rtt[pre][1] , 0 , n - 1 , 0 , k - getdis(x , now));
res += w1 + w2;
}
pre = now , now = dfa[now];
}
return res;
}
signed main()
{
//freopen("P6329_1.in","r",stdin);
//freopen("1.out","w",stdout);
n = read() , q = read();
for(int i = 1 ; i <= n ; i ++) a[i] = read();
for(int i = 1 ; i < n ; i ++)
{
int x,y;x = read() , y = read();
add(x , y) , add(y , x);
}
dfs(1 , 0);
//resiz(1 , 0);
mx[rt = 0] = Inf , S = n;
getrt(1 , 0) , resiz(rt , 0) , Build(rt);
//for(int i = 1 ; i <= n ; i ++) printf("!!!%d %d\n",i,dfa[i]);
for(int i = 1 ; i <= n ; i ++) upd(i , a[i]);
int lstans = 0;
for(int i = 1 ; i <= q ; i ++)
{
int opt,x,y;opt = read() , x = read() , y = read();
x ^= lstans , y ^= lstans;
if(opt == 0) write(lstans = qry(x , y)) , putchar('\n');
else
{
upd(x , y - a[x]);
a[x] = y;
}
}
return 0;
}