#10 WA求助
查看原帖
#10 WA求助
866613
sansesantongshun楼主2024/1/13 18:42
#include<bits/stdc++.h>
using namespace std;
int n,m,r,mod,a[100005],x,y,head[100005],cnt0=0,b[100005],c[100005],d[100005],e[100005],cnt=0,f[100005],g[100005],h[100005],aa[400005],bb[400005],k,z,ans;
struct node
{
	int next,to;
} edge[200005];
void add(int from,int to)
{
	edge[++cnt0]=(node){head[from],to};
	head[from]=cnt0;
}
void dfs1(int x,int f)
{
	int y,maxn=0;
	b[x]=f;
	c[x]=c[f]+1;
	d[x]=1;
	for (int i=head[x];i;i=edge[i].next)
	{
		y=edge[i].to;
		if (y!=f)
		{
			dfs1(y,x);
			d[x]+=d[y];
			if (d[y]>maxn)
			{
				maxn=d[y];
				e[x]=y;
			}
		}
	}
}
void dfs2(int x,int t)
{
	int y;
	f[x]=++cnt;
	g[cnt]=a[x];
	h[x]=t;
	if (e[x])
	{
		dfs2(e[x],t);
		for (int i=head[x];i;i=edge[i].next)
		{
			y=edge[i].to;
			if (y!=b[x] && y!=e[x])
			dfs2(y,y);
		}
	}
}
void build(int x,int l,int r)
{
	if (l==r)
	aa[x]=g[l];
	else
	{
		int mid=l+r>>1;
		build(x<<1,l,mid);
		build(x<<1|1,mid+1,r);
		aa[x]=(aa[x<<1]+aa[x<<1|1])%mod;
	}
}
void modify(int x,int bl,int br,int l,int r,int y)
{
	if (l<=bl && br<=r)
	{
		aa[x]=(aa[x]+(br-bl+1)*y)%mod;
		bb[x]=(bb[x]+y)%mod;
		return;
	}
	int mid=bl+br>>1;
	aa[x<<1]=(aa[x<<1]+(mid-bl+1)*bb[x])%mod;
	aa[x<<1|1]=(aa[x<<1|1]+(br-mid)*bb[x])%mod;
	bb[x<<1]=(bb[x<<1]+bb[x])%mod;
	bb[x<<1|1]=(bb[x<<1|1]+bb[x])%mod;
	bb[x]=0;
	if (l<=mid)
	modify(x<<1,bl,mid,l,r,y);
	if (mid<r)
	modify(x<<1|1,mid+1,br,l,r,y);
	aa[x]=(aa[x<<1]+aa[x<<1|1])%mod;
}
int query(int x,int bl,int br,int l,int r)
{
	if (l<=bl && br<=r)
	return aa[x];
	int mid=bl+br>>1,result=0;
	aa[x<<1]=(aa[x<<1]+(mid-bl+1)*bb[x])%mod;
	aa[x<<1|1]=(aa[x<<1|1]+(br-mid)*bb[x])%mod;
	bb[x<<1]=(bb[x<<1]+bb[x])%mod;
	bb[x<<1|1]=(bb[x<<1|1]+bb[x])%mod;
	bb[x]=0;
	if (l<=mid)
	result=(result+query(x<<1,bl,mid,l,r))%mod;
	if (mid<r)
	result=(result+query(x<<1|1,mid+1,br,l,r))%mod;
	return result;
}
int main()
{
	cin>>n>>m>>r>>mod;
	for (int i=1;i<=n;++i)
	scanf("%d",&a[i]);
	for (int i=1;i<n;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs1(r,0);
	dfs2(r,r);
	build(1,1,n);
	while (m--)
	{
		scanf("%d",&k);
		if (k==1)
		{
			scanf("%d%d%d",&x,&y,&z);
			while (h[x]!=h[y])
			{
				if (c[h[x]]<c[h[y]])
				swap(x,y);
				modify(1,1,n,f[h[x]],f[x],z);
				x=b[h[x]];
			}
			if (c[x]>c[y])
			swap(x,y);
			modify(1,1,n,f[x],f[y],z);
		}
		else if (k==2)
		{
			scanf("%d%d",&x,&y);
			ans=0;
			while (h[x]!=h[y])
			{
				if (c[h[x]]<c[h[y]])
				swap(x,y);
				ans=(ans+query(1,1,n,f[h[x]],f[x]))%mod;
				x=b[h[x]];
			}
			if (c[x]>c[y])
			swap(x,y);
			ans=(ans+query(1,1,n,f[x],f[y]))%mod;
			cout<<ans<<'\n';
		}
		else if (k==3)
		{
			scanf("%d%d",&x,&y);
			modify(1,1,n,f[x],f[x]+d[x]-1,y);
		}
		else
		{
			scanf("%d",&x);
			cout<<query(1,1,n,f[x],f[x]+d[x]-1)<<'\n';
		}
	}
}
2024/1/13 18:42
加载中...