我大抵是 WA 了,但这无耻的强制在线和每个点庞大的数据量让我无法从测试点中获得更多线索。我自然是不会轻易放了它跑的,自然是不会的。我点上一支烟,与它鏖战至深夜,一抬头发现那满屏的五彩斑斓,似要说出抑扬顿挫的话来,我便赶忙来讨论区求助力。
调了两天了,除了训练都在调,问题是答案错误,强制在线解密错了所以爆 RE ,题解和讨论区都翻遍了/kk。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
long long a[N];
inline long long Read()
{
long long x=0;
char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
{
x=(x<<1)+(x<<3)+c-48;
c=getchar();
}
return x;
}
int Head[N],To[N<<1],Nxt[N<<1],Etot;
void Addedge(int x,int y)
{
To[++Etot]=y;
Nxt[Etot]=Head[x];
Head[x]=Etot;
}
int Size[N],F[N],rt,Fa[N],fa[N][20];
bool vis[N];
int Dep[N];
int Lca(int x,int y)
{
if(x==y)
return x;
if(Dep[x]<Dep[y])
swap(x,y);
for(int i=17;i>=0;i--)
if(Dep[fa[x][i]]>=Dep[y])
x=fa[x][i];
if(x==y)
return x;
for(int i=17;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int Dis(int x,int y)
{
int lca=Lca(x,y);
return Dep[x]+Dep[y]-Dep[lca]*2;
}
int cnt=0;
void Pre(int x,int pre)
{
Dep[x]=Dep[pre]+1;
fa[x][0]=pre;
for(int i=1;i<=17;i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=Head[x];i;i=Nxt[i])
{
int y=To[i];
if(y==pre)
continue;
Pre(y,x);
}
}
int tot,maxn;
void Getroot(int x,int pre)
{
Size[x]=1;
F[x]=0;
for(int i=Head[x];i;i=Nxt[i])
{
int y=To[i];
if(y==pre||vis[y])
continue;
Getroot(y,x);
Size[x]+=Size[y];
F[x]=max(F[x],Size[y]);
}
F[x]=max(F[x],tot-Size[x]);
if(F[x]<maxn)
rt=x,maxn=F[x];
}
vector<int>C[N][2];
void Gets(int x,int pre)
{
Size[x]=1;
for(int i=Head[x];i;i=Nxt[i])
{
int y=To[i];
if(y==pre||vis[y])
continue;
Gets(y,x);
Size[x]+=Size[y];
}
}
void Dfs(int x)
{
C[x][0].resize(Size[x]+3);
C[x][1].resize(Size[x]+4);
vis[x]=1;
for(int i=Head[x];i;i=Nxt[i])
{
int y=To[i];
if(vis[y])
continue;
rt=0;maxn=N<<1;tot=Size[y];
Getroot(y,0);
Gets(rt,0);
Fa[rt]=x;
Dfs(rt);
}
}
void Add(int rt,int x,int v,int t)
{
++x;
while(x<=Size[rt]+t)
{
C[rt][t][x]+=v;
x+=(x&-x);
}
}
int Query(int rt,int x,int t)
{
int ret=0;
++x;
x=min(x,Size[rt]+t);
while(x)
{
ret+=C[rt][t][x];
x-=(x&-x);
}
return ret;
}
void Change(int x,int y)
{
for(int z=x;z;z=Fa[z])
{
Add(z,Dis(x,z),y,0);
if(Fa[z])
Add(z,Dis(Fa[z],x),y,1);
}
}
long long Solve(int x,int y)
{
long long ret=Query(x,y,0);
for(int z=x;Fa[z];z=Fa[z])
{
int dis=Dis(Fa[z],x);
if(y<dis)
continue;
ret+=Query(Fa[z],y-dis,0)-Query(z,y-dis,1);
}
return ret;
}
int main()
{
int n=Read(),m=Read();
for(int i=1;i<=n;i++)
a[i]=Read();
for(int i=1;i<n;i++)
{
int x=Read(),y=Read();
Addedge(x,y);
Addedge(y,x);
}
Pre(1,0);
maxn=N<<1,tot=n;
Getroot(1,0);
Gets(rt,0);
Dfs(rt);
for(int i=1;i<=n;i++)
Change(i,a[i]);
long long lastans=0;
while(m--)
{
long long op=Read(),x=Read(),y=Read();
x^=lastans,y^=lastans;
if(!op)
printf("%lld\n",lastans=Solve(x,y));
else
Change(x,y-a[x]),a[x]=y,lastans=0;
}
return 0;
}