P6329点分树板子求条(玄关)
  • 板块学术版
  • 楼主rpyluogu
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/12/17 14:03
  • 上次更新2024/12/17 19:28:41
查看原帖
P6329点分树板子求条(玄关)
1049376
rpyluogu楼主2024/12/17 14:03

rt,RE0pts

#include<bits/stdc++.h>
using namespace std;
int ans,dep[100005],cnt,root,f[100005][20],fa[100005],res,u,v,a[100005],vis[100005],maxp[100005],dis[100005],sums,id,n,m,op,x,k,head[200005];
struct node{
	int to,nxt;
}e[200005];
struct node2{
	int l,r,sum;
}tr[7000005];
void quxiu(int &p,int x,int l,int r,int k){
	if(!p){
		p=++res;
	}
	if(l==r){
		tr[p].sum+=k;
		return ;
	}
	int mid=(l+r)>>1;
	if(x<=mid){
		quxiu(tr[p].l,x,l,mid,k);
	}
	else{
		quxiu(tr[p].r,x,mid+1,r,k);
	}
	tr[p].sum=tr[tr[p].l].sum+tr[tr[p].r].sum;
}
int qucha(int p,int x,int y,int l,int r){
	if(!p){
		return 0;
	}
	if(x<=l&&y>=r){
		return tr[p].sum;
	}
	int s=0;
	int mid=(l+r)>>1;
	if(x<=mid){
		s+=qucha(tr[p].l,x,y,l,mid);
	}
	if(y>mid){
		s+=qucha(tr[p].r,x,y,mid+1,r);
	}
	return s;
}
void add(int x,int y){
	e[++cnt].to=y;
	e[cnt].nxt=head[x];
	head[x]=cnt;
}
void dfs(int x,int pre){
	dis[x]=1;
	maxp[x]=0;
	for(register int i=head[x];i;i=e[i].nxt){
		if(e[i].to==pre||vis[e[i].to]){
			continue;
		}
		dfs(e[i].to,x);
		dis[x]+=dis[e[i].to];
		maxp[x]=max(maxp[x],dis[e[i].to]);
	}
	maxp[x]=max(maxp[x],sums-dis[x]);
	if(maxp[id]>maxp[x]){
		id=x;
	}
}
void dfs2(int x,int pre,int depth){
	dep[x]=depth;
	f[x][0]=pre;
	for(register int i=1;i<=17;i++){
		f[x][i]=f[f[x][i-1]][i-1];
	}
	for(register int i=head[x];i;i=e[i].nxt){
		if(e[i].to==pre){
			continue;
		}
		dfs2(e[i].to,x,depth+1);
	}
}
int LCA(int u,int v){
	if(dep[u]<dep[v]){
		swap(u,v);
	}
	for(register int i=17;i>=0;i--){
		if(dep[f[u][i]]>=dep[v]){
			u=f[u][i];
		}
	}
	if(u==v){
		return v;
	}
	for(register int i=17;i>=0;i--){
		if(f[u][i]!=f[v][i]){
			u=f[u][i];
			v=f[v][i];
		}
	}
	return f[u][0];
}
void build(int x){
	vis[x]=1;
	for(register int i=head[x];i;i=e[i].nxt){
		if(vis[e[i].to]){
			continue;
		}
		sums=dis[e[i].to];
		maxp[0]=1e9;
		id=0;
		dfs(e[i].to,0);
		sums=dis[e[i].to];
		maxp[0]=1e9;
		dfs(id,0);
		fa[id]=x;
		build(id);
	}
}
void modify(int x,int k){
	for(register int i=x;i;i=fa[i]){
		quxiu(i,dep[x]+dep[i]-dep[LCA(i,x)]*2,0,1e5,k);
		if(fa[i]){
			int pos=i+n;
		//	cout<<pos<<'\n';
			quxiu(pos,dep[x]+dep[fa[i]]-dep[LCA(x,fa[i])]*2,0,1e5,k);
		}
	}
}
void query(int x,int k){
	int last=0;
	for(register int i=x;i;i=fa[i]){
		if(dep[x]+dep[i]-dep[LCA(x,i)*2]<=k){
			ans+=qucha(i,0,k-dep[x]-dep[i]+dep[LCA(x,i)]*2,0,1e5);
			int pos=last+n;
			if(last)ans-=qucha(pos,0,k-dep[last]-dep[i]+dep[LCA(last,i)]*2,0,1e5);
		}	
		last=i;
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(register int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(register int i=1;i<=n-1;i++){
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	maxp[0]=1e9;
	sums=n;
	dfs2(1,0,1);
	dfs(1,0);
	maxp[0]=1e9;
	sums=n;	
	dfs(id,0);
	res=n*2;
	build(id);
	for(register int i=1;i<=n;i++){
		modify(i,a[i]);
	}
	for(register int i=1;i<=m;i++){
		cin>>op>>x>>k;
		x^=ans;
		k^=ans;
		//cout<<x<<" "<<k<<" "<<ans<<'\n';
		if(op==1){
			modify(x,k-a[x]);
			a[x]=k;
		}
		else{
			ans=0;
			query(x,k);
			cout<<ans<<'\n';
		}
	}
	return 0;
}
2024/12/17 14:03
加载中...