蒟蒻30分求助
查看原帖
蒟蒻30分求助
407604
Griseo_nya楼主2021/1/5 00:49
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=200006;
struct bian{
	int bef,to;
}edge[maxn+1];
long long p;
int w[maxn+1],wn[maxn+1],size[maxn+1];
int n,num,m,r,tp[maxn+1],idnum,head[maxn+1],deep[maxn+1],zson[maxn+1],father[maxn+1],id[maxn+1];
void dfs1(int x,int fa,int d){
	deep[x]=d;
	size[x]=1;
	int zon=-1;
	father[x]=fa;
	for(int i=head[x];i!=0;i=edge[i].bef){
		int qwq=edge[i].to;
		if(qwq==fa)continue;
		dfs1(qwq,x,d+1);
		size[x]+=size[qwq];
		if(size[qwq]>zon){
			zson[x]=qwq;
			zon=size[qwq];
		}
	}
}
void dfs2(int x,int topp){
	id[x]=++idnum;
	tp[x]=topp;
	wn[idnum]=w[x];
	if(zson[x]){
		dfs2(zson[x],topp);
		for(int i=head[x];i!=0;i=edge[i].bef){
			int u=edge[i].to;
			if(!id[u])
			dfs2(u,u);
	}
	}
}
void addedge(int u,int v){
	edge[++num].to=v;
	edge[num].bef=head[u];
	head[u]=num;
}
struct tre{
	int l,r,w,siz,tag;
}shu[2*maxn+1];
void build(int k,int l,int r){
	shu[k].l=l;
	shu[k].r=r;
	shu[k].siz=r-l+1;
	if(l==r){
		shu[k].w=wn[l];
		return;
	}
	int mid=(l+r)/2;
	build(k*2,l,mid);
	build(k*2+1,mid+1,r);
	shu[k].w=(shu[k*2].w+shu[k*2+1].w+p)%p;
} 
void push(int k){
	if(!shu[k].tag)return;
		shu[k*2].w=(shu[k*2].w+shu[k*2].siz*shu[k].tag)%p;
    	shu[k*2+1].w=(shu[k*2+1].w+shu[k*2+1].siz*shu[k].tag)%p;
    	shu[k*2].tag=(shu[k*2].tag+shu[k].tag)%p;
    	shu[k*2+1].tag=(shu[k*2+1].tag+shu[k].tag)%p;
    	shu[k].tag=0;
}
void jia(int k,int l,int r,int v){
	if(l<=shu[k].l&&r>=shu[k].r){
		shu[k].w+=shu[k].siz*v;
        shu[k].tag+=v;
        return;
	}
	push(k);
	int mid=(shu[k].l+shu[k].r)/2;
	if(l<=mid)jia(k*2,l,r,v);
	if(r>mid)jia(k*2+1,l,r,v);
	shu[k].w=(shu[k*2].w+shu[k*2+1].w+p)%p;
}
int sum(int k,int l,int r){
	int ans=0;
	if(shu[k].l>=l&&shu[k].r<=r){
		return shu[k].w;
		
	}
	push(k);
	int mid=(shu[k].l+shu[k].r)/2;
	if(l<=mid)ans=(ans+sum(k*2,l,r))%p;
	if(r>mid)ans=(ans+sum(k*2+1,l,r))%p;
	return ans;
}
int tsum(int a,int b){
	int ans=0;
	while(tp[a]!=tp[b]){
		if(deep[a]<deep[b])swap(a,b);
		ans=(ans+sum(1,id[tp[a]],id[a]))%p;
		a=father[tp[a]];
	}
	if(deep[a]>deep[b])swap(a,b);
	ans=(ans+sum(1,id[a],id[b]))%p;
	return ans;
}
void tjia(int a,int b,int v){
	while(tp[a]!=tp[b]){
		if(deep[tp[a]]<deep[tp[b]])swap(a,b);
		jia(1,id[tp[a]],id[a],v);
		a=father[tp[a]];
	}
	if(deep[a]>deep[b])swap(b,a);
	jia(1,id[a],id[b],v);
}
#undef int
int main(){
	#define int long long
	#ifndef ONLINE_JUDGE
	freopen("P3384_2.in","r",stdin);

	#endif
	scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
	for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%lld%lld",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int op;
		scanf("%lld",&op);
		int a,b,c;
		switch(op){
			case 1:
				
				scanf("%lld%lld%lld",&a,&b,&c);
				c%=p;
				tjia(a,b,c);
				break;
			case 2:

				scanf("%lld%lld",&a,&b);
				printf("%lld\n",tsum(a,b));
				break;
			case 3:

				scanf("%lld%lld",&a,&b);
				jia(1,id[a],id[a]+size[a]-1,b%p);
				break;
			case 4:

				scanf("%lld",&a);
				printf("%lld\n",sum(1,id[a],id[a]+size[a]-1));
				break;
		}
	}
	return 0;
}
2021/1/5 00:49
加载中...