40分
查看原帖
40分
528787
OIer_Automation楼主2023/12/17 10:12
#include <bits/stdc++.h>
using namespace std;

const int N=2e5;
int n,m,u,v,opt,x,k,y,ans;
int val[N+5];

struct Edge{
	int cnt=1;
	int head[N+5],to[(N<<1)+5],nxt[(N<<1)+5];
	void addEdge(int u,int v){
		to[cnt]=v,nxt[cnt]=head[u],head[u]=cnt++;
		return ;
	}
}edge;

struct Lca{
	int faz[N+5],siz[N+5],top[N+5],dep[N+5],son[N+5];
	void getSon(int u,int f){
		siz[u]=1,son[u]=0;
		for(int i=edge.head[u];i;i=edge.nxt[i]){
			int v=edge.to[i];
			if(v==f)continue;
			dep[v]=dep[u]+1;
			faz[v]=u;
			getSon(v,u);
			siz[u]+=siz[v];
			if(siz[v]>siz[son[u]])son[u]=v;
		}
		return ;
	}
	void getList(int u,int rt){
		top[u]=rt;
		if(son[u])getList(son[u],rt);
		for(int i=edge.head[u];i;i=edge.nxt[i]){
			int v=edge.to[i];
			if(v==faz[u]||v==son[u])continue;
			getList(v,v);
		}
		return ;
	}
	int lca(int u,int v){
		while(top[u]!=top[v]){
			if(dep[top[u]]<dep[top[v]])swap(u,v);
			u=faz[top[u]];
		}
		if(dep[u]<dep[v])swap(u,v);
		return v;
	}
	int getDis(int x,int y){
		return dep[x]+dep[y]-2*dep[lca(x,y)];
	}
}lca;

struct SegTree{
	int cnt;
	int root[N+5],sum[(N<<5)+5],lc[(N<<5)+5],rc[(N<<5)+5];
	void pushup(int u){
		sum[u]=sum[lc[u]]+sum[rc[u]];
		return ;
	}
	void change(int &u,int l,int r,int pos,int v){
		if(!u)u=++cnt;
		if(l==r){
			sum[u]+=v;
			return ;
		}
		int mid=(l+r)>>1;
		if(pos<=mid)change(lc[u],l,mid,pos,v);
		else change(rc[u],mid+1,r,pos,v);
		pushup(u);
		return ;
	}
	int query(int u,int l,int r,int x,int y){
		if(!u||r<x||l>y)return 0;
		if(x<=l&&r<=y)return sum[u];
		int mid=(l+r)>>1;
		return query(lc[u],l,mid,x,y)+query(rc[u],mid+1,r,x,y); 
	}
}sg,ch;

struct PointTree{
	int root;
	int siz[N+5],mxp[N+5],faz[N+5],dis[N+5][25],dep[N+5];
	bool vis[N+5];
	void getRoot(int u,int f,int tot){
		siz[u]=1,mxp[u]=0;
		for(int i=edge.head[u];i;i=edge.nxt[i]){
			int v=edge.to[i];
			if(v==f||vis[v])continue;
			siz[u]=siz[v]+1;
			mxp[u]=max(mxp[u],siz[v]);
		}
		mxp[u]=max(mxp[u],tot-siz[u]);
		if(mxp[u]<mxp[root])root=u;
		return ;
	}
	void buildSg(int u,int f,int rt,int d){
		sg.change(sg.root[rt],0,n,d,val[u]);
		for(int i=edge.head[u];i;i=edge.nxt[i]){
			int v=edge.to[i];
			if(v==f||vis[v])continue;
			buildSg(v,u,rt,d+1);
		}
		return ;
	}
	void buildCh(int u,int f,int rt,int d){
		ch.change(ch.root[rt],0,n,d,val[u]);
		for(int i=edge.head[u];i;i=edge.nxt[i]){
			int v=edge.to[i];
			if(v==f||vis[v])continue;
			buildCh(v,u,rt,d+1);
		}
		return ;
	}
	void build(int u){
		vis[u]=true;
		buildSg(u,0,u,0);
		for(int i=edge.head[u];i;i=edge.nxt[i]){
			int v=edge.to[i];
			if(vis[v])continue;
			root=0;
			getRoot(v,0,siz[v]);
			buildCh(v,0,root,1);
			faz[root]=u,dep[root]=dep[u]+1;
			build(root);
		}
		return ;
	}
	void init(){
		mxp[0]=n;
		getRoot(1,0,n);
		build(root);
		lca.getSon(1,0),lca.getList(1,1);
		for(int i=1;i<=n;i++){
			for(int j=i;j;j=faz[j])dis[i][dep[i]-dep[j]]=lca.getDis(i,j);
		}
		return ;
	}
	void change(int x,int y){
		sg.change(sg.root[x],0,n,0,y-val[x]);
		for(int i=x;faz[i];i=faz[i]){
			int d=dis[x][dep[x]-dep[faz[i]]];
			sg.change(sg.root[faz[i]],0,n,d,y-val[x]);
			ch.change(ch.root[i],0,n,d,y-val[x]) ;
		}
		val[x]=y;
		return ;
	}
	int query(int x,int y){
		int res=sg.query(sg.root[x],0,n,0,y);
		for(int i=x;faz[i];i=faz[i]){
			int d=dis[x][dep[x]-dep[faz[i]]];
			res+=sg.query(sg.root[faz[i]],0,n,0,y-d);
			res-=ch.query(ch.root[i],0,n,0,y-d);
		}
		return res;
	}
}pt;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&val[i]);
	for(int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		edge.addEdge(u,v),edge.addEdge(v,u);
	}
	pt.init();
	for(int i=1;i<=m;i++){
		scanf("%d",&opt);
		if(opt==0){
			scanf("%d%d",&x,&k);
			x^=ans,k^=ans;
			ans=pt.query(x,k);
			printf("%d\n",ans);
		}else{
			scanf("%d%d",&x,&y);
			x^=ans,y^=ans;
			pt.change(x,y);
		}
	}
	return 0;
}
2023/12/17 10:12
加载中...