树剖板子求助,纯度100%
查看原帖
树剖板子求助,纯度100%
370648
柠檬布丁吖楼主2023/4/2 19:58
//inline void dfs1(int x,int f,int deep){
//	dep[x]=deep;
//	fa[x]=f;
//	siz[x]=1;
//	int maxson=-1;
//	for(int i=beg[x];i;i=ne[i]){
//		int y=to[i];
//		if(y==f) continue;
//		dfs1(y,x,deep+1);
//		siz[x]+=siz[y];
//		if(siz[y]>maxson) son[x]=y;maxson=siz[y];
//	}
//}
//
//inline void dfs2(int x,int topf){
//	id[x]=++cnt;
//	wt[cnt]=w[x];
//	top[x]=topf;
//	if(!son[x]) return;
//	dfs2(son[x],topf);
//	for(int i=beg[x];i;i=ne[i]){
//		int y=to[i];
//		if(y==fa[x]||y==son[x]) continue;
//		dfs2(y,y);
//	}
//}


#include<bits/stdc++.h>

using namespace std;

#define ll long long
#define mid ((l+r)>>1)
#define len (r-l+1)

inline int read() {
	int ret=0,f=1;
	char c=getchar();
	for(; c<'0'||c>'9'; c=getchar()) if(c=='-') c=getchar();
	for(; c>='0'&&c<='9'; c=getchar()) ret=ret*10+c-'0';
	return ret*f;
}

int n,m,r,mod;
const int maxn=2e6+55;

int e,beg[maxn],nex[maxn],to[maxn],w[maxn],wt[maxn];

int a[maxn<<2],laz[maxn<<2];

int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
int res=0;

inline void add(int x,int y) {
	to[++e]=y;
	nex[e]=beg[x];
	beg[x]=e;
}

inline void dfs1(int x,int f,int deep) {
	dep[x]=deep;
	fa[x]=f;
	siz[x]=1;
	int maxson=-1;
	for(int i=beg[x]; i; i=nex[x]) {
		int y=to[i];
		if(y==f) continue;
		dfs1(y,x,deep+1);
		siz[x]+=siz[y];
		if(siz[y]>maxson) son[x]=y;
		maxson=siz[y];
	}
}

inline void dfs2(int x,int topf) {
	id[x]=++cnt;
	wt[cnt]=w[x];
	top[x]=topf;
	if(!son[x]) return;
	dfs2(son[x],topf);
	for(int i=beg[x]; i; i=nex[i]) {
		int y=to[i];
		if(y==fa[x]||y==son[x]) continue;
		dfs2(y,y);
	}
}


inline void build(int rt,int l,int r) {
	if(l==r) {
		a[rt]=wt[l];
		if(a[rt]>mod) a[rt]%=mod;
		return;
	}

	build(rt<<1,l,mid);
	build(rt<<1||1,mid+1,r);
	a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}

void pushdown(int rt,int lenn) {
	laz[rt<<1]+=laz[rt];
	laz[rt<<1|1]+=laz[rt];
	a[rt<<1]+=laz[rt]*(lenn-(lenn>>1));
	a[rt<<1|1]+=laz[rt]*(lenn>>1);
	a[rt<<1]%=mod;
	a[rt<<1|1]%=mod;
	laz[rt]=0;
}

inline void update(int rt,int l,int r,int L,int R,int k) {
	if(L<=l&&r<=R) {
		laz[rt]+=k;
		a[rt]+=k*len;
	} else {
		if(laz[rt]) pushdown(rt,len);
		
		if(L<=mid) update(rt<<1,l,mid,L,R,k);
		
		if(R>mid) update(rt<<1|1,mid+1,r,L,R,k);
		
		a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
	}
}

inline void uprange(int x,int y,int k) {
	k%=mod;
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];
	}

	if(dep[x]>dep[y]) swap(x,y);
	update(1,1,n,id[x],id[y],k);
}

inline void query(int rt,int l,int r,int L,int R) {
	if(L<=l&&r<=R) {
		res+=a[rt];
		res%=mod;
		return;
	} else {
		if(laz[rt]) pushdown(rt,len);
		if(L<=mid) query(rt<<1,l,mid,L,R);
		if(R>mid) query(rt<<1|1,mid+1,r,L,R);
	}
}

inline int qrange(int x,int y) {
	int ans=0;
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		res=0;
		query(1,1,n,id[top[x]],id[x]);
		ans+=res;
		ans%=mod;
		x=fa[top[x]];
	}

	if(dep[x]>dep[y]) swap(x,y);
	res=0;
	query(1,1,n,id[x],id[y]);
	ans+=res;
	return ans%mod;
}

inline void upson(int x,int k) {
	update(1,1,n,id[x],id[x]+siz[x]-1,k);
}

inline int qson(int x) {
	res=0;
	query(1,1,n,id[x],id[x]+siz[x]-1);
	return res;
}

signed main(void) {

	n=read();
	m=read();
	r=read();
	mod=read();

	for(int i=1; i<=n; i++) {
		w[i]=read();
	}

	for(int i=1; i<n-1; i++) {
		int a,b;
		a=read();
		b=read();
		add(a,b);
		add(b,a);
	}

	dfs1(r,0,1);
	dfs2(r,r);

	build(1,1,n);

	while(m--) {
		int k,x,y,z;
		k=read();
		if(k==1) {
			x=read();
			y=read();
			z=read();
			uprange(x,y,z);
		}

		if(k==2) {
			x=read();
			y=read();
			printf("%d\n",qrange(x,y));
		}

		if(k==3) {
			x=read();
			z=read();

			upson(x,y);
		}

		if(k==4) {
			x=read();
			printf("%d\n",qson(x));
		}
	}

	return 0;
}
2023/4/2 19:58
加载中...