树剖板子求调,wa10pts
查看原帖
树剖板子求调,wa10pts
556455
AllureLove2410喜欢若彤楼主2022/12/4 18:31

rt,马蜂自认为舒服

#include<bits/stdc++.h>
using namespace std;
const int xrt=1e5+3;
int dep[xrt],fa[xrt],son[xrt],size[xrt];
int idx[xrt],rev[xrt],top[xrt];
int n,m,r,p;
int dis[xrt];
int head[xrt];
struct zsm{
	int to;
	int next;
}e[xrt<<1];
struct Tree{
	int l,r;
	int sum;
	int lazy;
}t[xrt<<2];
int cnt,tot;
void insery(int x,int y){
	e[++cnt].to=y;
	e[cnt].next=head[x];
	head[x]=cnt;
}
void dfs1(int x,int f){
	size[x]=1;
	for(int i=head[x];i;i=e[i].next){
		int t=e[i].to;
		if(t==f)continue;
		dep[t]=dep[x]+1;
		fa[t]=x;
		dfs1(t,x);
		size[x]+=size[t];
		if(size[t]>size[son[x]]){
			son[x]=t;
		}
	}
	return;
}
void dfs2(int x,int t){
	top[x]=t;
	idx[x]=++tot;
	rev[tot]=x;
	if(!son[x])return;
	dfs2(son[x],t);
	for(int i=head[x];i;i=e[i].next){
		int t=e[i].to;
		if(t!=fa[x]&&t!=son[x]){
			dfs2(t,t);
		}
	}
	return;
}
void build(int x,int l,int r){
	t[x].l=l,t[x].r=r;
	if(l==r){
		t[x].sum=dis[rev[l]];
		return;
	}
	int mid=l+((r-l)>>1);
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
	return;
}
void down(int x){
	if(t[x].lazy){
		t[x<<1].sum+=(t[x<<1].r-t[x<<1].l+1)*t[x].lazy;
		t[x<<1].lazy+=t[x].lazy;
		t[x<<1|1].sum+=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x].lazy;
		t[x<<1|1].lazy+=t[x].lazy;
		t[x].lazy=0;
	}
}
void add(int x,int l,int r,int k){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].sum+=(t[x].r-t[x].l+1)*k;
		t[x].lazy+=k;
		return;
	}
	down(x);
	int mid=t[x].l+((t[x].r-t[x].l)>>1);
	if(l<=mid){
		add(x<<1,l,r,k);
	}
	if(r>mid){
		add(x<<1|1,l,r,k);
	}
	return;
}
int finds(int x,int l,int r){
	if(t[x].l>=l&&t[x].r<=r){
		return t[x].sum;
	}
	down(x);
	int mid=t[x].l+((t[x].r-t[x].l)>>1);
	int ans=0;
	if(l<=mid){
		ans+=finds(x<<1,l,r);
	}
	if(r>mid){
		ans+=finds(x<<1|1,l,r);
	}
	return ans;
}
void work1(int x,int y,int z){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		add(1,idx[top[x]],idx[x],z%p);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]){
		swap(x,y);
	}
	add(1,idx[x],idx[y],z%p);
	return;
}
void work2(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		ans=(ans+finds(1,idx[top[x]],idx[x]))%p;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]){
		swap(x,y);
	}
	ans=(ans+finds(1,idx[x],idx[y]))%p;
	cout<<ans<<"\n";
	return;
}
void work3(int x,int z){
	add(1,idx[x],idx[x]+size[x]-1,z%p);
}
void work4(int x){
	cout<<finds(1,idx[x],idx[x]+size[x]-1)%p<<"\n";
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++){
		cin>>dis[i];
	}
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		insery(u,v);
		insery(v,u);
	}
	dep[r]=1;
	dfs1(r,0);
	dfs2(r,1);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int op;
		cin>>op;
		if(op==1){
			int x,y,z;
			cin>>x>>y>>z;
			work1(x,y,z);
		}else if(op==2){
			int x,y;
			cin>>x>>y;
			work2(x,y);
		}else if(op==3){
			int x,z;
			cin>>x>>z;
			work3(x,z);
		}else if(op==4){
			int x;
			cin>>x;
			work4(x);
		}
	}
	return 0;
}
2022/12/4 18:31
加载中...