RE+WA,喜提0分()。
希望有大佬帮调一下,谢谢。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
struct node
{
int ls,rs,sum;
};
int n,m,a[N],dep[N],pre[N][30];
vector<int> e[N];
int rot,n2,ind[2],rt[2][N],fa[N],siz[N],mx[N],son[N];
bool vis[N];
node t[2][N*50];
void dfs1(int x,int f)
{
dep[x]=dep[f]+1;
pre[x][0]=f;
for(int i=1;i<=20;i++)
{
pre[x][i]=pre[pre[x][i-1]][i-1];
}
for(auto y:e[x])
{
if(y==f)
{
continue;
}
dfs1(y,x);
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
{
swap(x,y);
}
for(int i=20;i>=0;i--)
{
if(dep[pre[x][i]]>=dep[y])
{
x=pre[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=20;i>=0;i--)
{
if(pre[x][i]!=pre[y][i])
{
x=pre[x][i];
y=pre[y][i];
}
}
return pre[x][0];
}
int getdis(int x,int y)
{
int z=lca(x,y);
return dep[x]+dep[y]-dep[z]*2;
}
void getrt(int x,int f)
{
siz[x]=1;
mx[x]=0;
for(auto y:e[x])
{
if(y==f||vis[y])
{
continue;
}
getrt(y,x);
siz[x]+=siz[y];
mx[x]=max(mx[x],siz[y]);
}
mx[x]=max(mx[x],n2-siz[x]);
if(!rot||mx[x]<mx[rot])
{
rot=x;
}
}
void getsiz(int x,int f)
{
siz[x]=1;
for(auto y:e[x])
{
if(y==f||vis[y])
{
continue;
}
getrt(y,x);
siz[x]+=siz[y];
}
}
void dfs2(int x)
{
getsiz(x,0);
vis[x]=1;
son[x]=1;
for(auto y:e[x])
{
if(vis[y])
{
continue;
}
rot=0;n2=siz[y];
getrt(y,0);
fa[rot]=x;
int z=rot;
dfs2(rot);
son[x]+=son[z];
}
}
void update(int tp,int &p,int l,int r,int x,int y)
{
if(!p)
{
p=++ind[tp];
}
if(l==r)
{
t[tp][p].sum+=y;
return;
}
int mid=(l+r)/2;
if(x<=mid)
{
update(tp,t[tp][p].ls,l,mid,x,y);
}else
{
update(tp,t[tp][p].rs,mid+1,r,x,y);
}
t[tp][p].sum=t[tp][t[tp][p].ls].sum+t[tp][t[tp][p].rs].sum;
}
int query(int tp,int p,int l,int r,int nl,int nr)
{
if(!p)
{
return 0;
}
if(nl<=l&&r<=nr)
{
return t[tp][p].sum;
}
int mid=(l+r)/2,ret=0;
if(nl<=mid)
{
ret+=query(tp,t[tp][p].ls,l,mid,nl,nr);
}
if(nr>mid)
{
ret+=query(tp,t[tp][p].rs,mid+1,r,nl,nr);
}
return ret;
}
void work1(int x,int y)
{
int now=x;
while(now)
{
update(0,rt[0][now],0,son[now],getdis(now,x),y);
if(fa[now])
{
update(1,rt[1][now],0,son[fa[now]],getdis(fa[now],x),y);
}
now=fa[now];
}
}
int work2(int x,int y)
{
int ret=0,lst=0,now=x;
while(now)
{
int t1=getdis(now,x);
if(t1>y)
{
lst=now;
now=fa[now];
continue;
}
ret+=query(0,rt[0][now],0,son[now],0,y-t1);
if(lst)
{
ret-=query(1,rt[1][lst],0,son[now],0,y-t1);
}
lst=now;
now=fa[now];
}
return ret;
}
signed main()
{
int op,x,y;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
cin>>x>>y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs1(1,0);
rot=0;n2=n;
getrt(1,0);
dfs2(rot);
for(int i=1;i<=n;i++)
{
work1(i,a[i]);
}
while(m--)
{
cin>>op>>x>>y;
if(op==0)
{
cout<<work2(x,y)<<"\n";
}else
{
work1(x,y-a[x]);
a[x]=y;
}
}
}