救救孩子,WA 20 蒟蒻求调
查看原帖
救救孩子,WA 20 蒟蒻求调
575901
jcaidyhl楼主2022/7/22 22:44
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
inline int read(){
	int f=1,x=0;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int n,m,p,rt,a[N];
int u,v,w;
int head[N],nxt[N<<1],to[N<<1],cnt=0;
void add(int u,int v)
{
	nxt[++cnt]=head[u];
	to[cnt]=v;
	head[u]=cnt;
}
int num[N],renum[N],siz[N],son[N],tp[N],fa[N],dep[N];
void dfs1(int x,int f)
{
	siz[x]=1;
	fa[x]=f;
	dep[x]=dep[f]+1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==f) continue;
		dfs1(y,x);
		siz[x]+=siz[y];
		if(siz[y]>siz[son[x]]) son[x]=y;
	}
}
void dfs2(int x,int p)
{
	tp[x]=p;
	num[x]=++cnt;
	renum[cnt]=x;
	if(!son[x]) return;
	dfs2(son[x],p);
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa[x]||y==son[x]) continue;
		dfs2(y,y);
	}
}
int sum[N<<2],lat[N<<2];
void pushup(int rt)
{
	sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%p;
}
void pushdown(int l,int r,int rt)
{
	if(!lat[rt]) return;
	int mid=(l+r)>>1;
	sum[rt<<1]=(sum[rt<<1]+lat[rt]*(mid-l+1))%p*1LL;
	sum[rt<<1|1]=(sum[rt<<1|1]+lat[rt]*(r-mid))%p*1LL;
	lat[rt<<1]=(lat[rt<<1]+lat[rt])%p;
	lat[rt<<1|1]=(lat[rt<<1|1]+lat[rt])%p;
	lat[rt]=0;
}
void buildup(int rt,int l,int r)
{
	if(l==r)
	{
		sum[rt]=a[renum[l]]%p;
		return;
	}
	int mid=(l+r)>>1;
	buildup(rt<<1,l,mid);
	buildup(rt<<1|1,mid+1,r);
	pushup(rt);
}
int query(int rt,int L,int R,int l,int r)
{
	if(L==l&&r==R)
	{
		return sum[rt];
	}
	pushdown(L,R,rt);
	int mid=(L+R)>>1;
	if(mid>=r) return query(rt<<1,L,mid,l,r);
	else if(mid<l) return query(rt<<1|1,mid+1,R,l,r);
	else return ((query(rt<<1,L,mid,l,mid)+query(rt<<1|1,mid+1,R,mid+1,r))%p+p)%p;
}
void update(int rt,int L,int R,int l,int r,int x)
{
	if(L==l&&r==R)
	{
		sum[rt]=((sum[rt]+x*(l-r+1))%p+p)%p;
		lat[rt]=((lat[rt]+x)%p+p)%p;
		return;
	}
	pushdown(L,R,rt);
	int mid=(L+R)>>1;
	if(mid>=r) update(rt<<1,L,mid,l,r,x);
	else if(mid<l) update(rt<<1|1,mid+1,R,l,r,x);
	else update(rt<<1,L,mid,l,mid,x),update(rt<<1|1,mid+1,R,mid+1,r,x);
	pushup(rt);
}
int od;
void lcanc(int x,int y,int f,int w)
{
	int res=0;
	while(tp[x]!=tp[y])
	{
		if(dep[tp[x]]>dep[tp[y]]) swap(x,y);
		if(f) update(1,1,n,num[tp[y]],num[y],w);
		else res=(res+query(1,1,n,num[tp[y]],num[y]))%p;
		y=fa[tp[y]];
	}
	if(dep[y]>dep[x]) swap(x,y);
	if(f) update(1,1,n,num[y],num[x],w);
	else 
	{
		res=(res+query(1,1,n,num[y],num[x]))%p;
		printf("%lld\n",res);
	}
}
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read();
	m=read();
	rt=read();
	p=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<n;i++)
	{
		u=read();
		v=read();
		add(u,v);
		add(v,u);
	}
	cnt=0;
	dfs1(rt,0);
	dfs2(rt,rt);
	buildup(1,1,n);
	for(int i=1;i<=m;i++)
	{
		od=read();
		if(od==1)
		{
			u=read();
			v=read();
			w=read();
			w%=p;
			lcanc(u,v,1,w);
		}else if(od==2)
		{
			u=read();
			v=read();
			lcanc(u,v,0,0);
		}else if(od==3)
		{
			u=read();
			w=read();
			w%=p;
			update(1,1,n,num[u],num[u]+siz[u]-1,w);
		}else
		{
			u=read();
			printf("%lld\n",query(1,1,n,num[u],num[u]+siz[u]-1));
		}
	}
	return 0;
}
2022/7/22 22:44
加载中...