20分求调
查看原帖
20分求调
362167
b1468821672楼主2022/10/11 18:25
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=300005;
struct edge
{
	long long to;
	long long nxt;
	long long w,wt;
}e[maxn*2];
struct tree
{
	long long l,r;
	long long add,pre;
}t[maxn*4];
long long cnt,n,m,r,p,df;
long long head[maxn*4];
long long son[maxn*2],deep[maxn*2],fa[maxn*2],siz[maxn*2],dfn[maxn*2],top[maxn*2];
void addedge(long long u,long long v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
void build(long long i,long long l,long long r)
{
	t[i].l=l,t[i].r=r;
	if(l==r)
	{
		t[i].pre=e[l].wt;
		return;
	}
	long long mid=l+r>>1;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	t[i].pre=(t[i*2].pre+t[i*2+1].pre)%p;
}
void push_down(long long i)
{
	if(t[i].add)
	{
		t[i*2].pre+=t[i].add*(t[i*2].r-t[i*2].l+1)%p;
    	t[i*2+1].pre+=t[i].add*(t[i*2+1].r-t[i*2+1].l+1)%p;
		t[i*2].add+=t[i].add;
     	t[i*2+1].add+=t[i].add;
     	t[i].add=0;
	}	 
}
void updata(long long i,long long l,long long r,long long m)
{
	if(t[i].l>=l&&t[i].r<=r)
	{
		t[i].pre+=m*(t[i].r-t[i].l+1)%p;
		t[i].add+=m;
		return;
	}
	push_down(i); 
	long long mid=t[i].l+t[i].r>>1;
	if(l<=mid)updata(i*2,l,r,m);
	if(r>mid)updata(i*2+1,l,r,m);
	t[i].pre=(t[i*2].pre+t[i*2+1].pre)%p;
}
long long query(long long i,long long l,long long r)
{
	if(t[i].l>=l&&t[i].r<=r)
	{
		return t[i].pre;
	}
	push_down(i);
	long long mid=t[i].l+t[i].r>>1;
	long long ans=0;
	if(l<=mid)ans=(ans+query(i*2,l,r))%p;
	if(r>mid)ans=(ans+query(i*2+1,l,r))%p;
	return ans%p;
}
void dfs1(long long x,long long f,long long len)
{
	deep[x]=len;
	fa[x]=f;
	siz[x]=1;
	for(long long i=head[x];i;i=e[i].nxt)
	{
		int y=e[i].to;
		if(y==f)continue;
		dfs1(y,x,len+1);
		siz[x]+=siz[y];
		if(siz[y]>siz[son[x]])
		{
			son[x]=y;
		}
	}
}
void dfs2(long long x,long long tp)
{
	top[x]=tp;
	dfn[x]=++df;
	e[df].wt=e[x].w;
	if(!son[x])return;
	dfs2(son[x],tp);
	for(long long i=head[x];i;i=e[i].nxt)
	{
		long long y=e[i].to;
		if(y==fa[x]||y==son[x])continue;
		dfs2(y,y);
	}
}
void tree_add(long long x,long long y,long long val)
{
	while(top[x]!=top[y])
	{
		if(deep[x]<deep[y])swap(x,y);
		updata(1,dfn[top[x]],dfn[x],val);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])swap(x,y);
	updata(1,dfn[x],dfn[y],val);
}
void tree_check(long long x,long long y)
{
	long long ans=0;
	while(top[x]!=top[y])
	{
		if(deep[x]<deep[y])swap(x,y);
		ans=(ans+query(1,dfn[top[x]],dfn[x]))%p;
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])swap(x,y);
	ans=(ans+query(1,dfn[x],dfn[y]))%p;
	cout<<ans%p<<endl;
}
int main()
{
	cin>>n>>m>>r>>p;
	for(long long i=1;i<=n;i++)
	{
		cin>>e[i].w;
		e[i].w%=p;
	}
	for(long long i=1;i<n;i++)
	{
		long long a,b;
		cin>>a>>b;
		addedge(a,b);
		addedge(b,a);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,1,n);
	for(long long i=1;i<=m;i++)
	{
		long long f,x,y,z;
		cin>>f>>x;
		if(f==1)
		{
			cin>>y>>z;
			tree_add(x,y,z);
		}
		if(f==2)
		{
			cin>>y;
			tree_check(x,y);
		}
		if(f==3)
		{
			cin>>z;
			updata(1,dfn[x],dfn[x]+siz[x]-1,z);
		}
		if(f==4)
		{
			cout<<query(1,dfn[x],dfn[x]+siz[x]-1)%p<<endl;
		}
	}
}
2022/10/11 18:25
加载中...