70pts求助
查看原帖
70pts求助
229919
一E孤行楼主2021/7/2 21:31
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
#define int long long
#define maxn 100008
int tot,head[maxn],cnt,mod,n,m,r;
struct aaa{
	int to,next;
}a[maxn];
struct bbb{
	int sum,l,r,lazy;
}t[40*maxn];
int w[maxn];
struct ccc{
	int size,deep,dfn,num,top,fa,son;
}tree[40*maxn];
void add(int x,int y)
{
	a[tot].to=y;
	a[tot].next=head[x];
	head[x]=tot++;
}
void pushdown(int id)
{
	int l=t[id].l;
	int r=t[id].r;
	int mid=(l+r)>>1;
	if(t[id].lazy) 
	{
		t[id<<1].sum+=t[id].lazy*(mid-l+1)%mod;
	    t[id<<1|1].sum+=t[id].lazy*(r-mid)%mod;
	    t[id<<1].lazy+=t[id].lazy%mod;
	    t[id<<1|1].lazy+=t[id].lazy%mod;
	    t[id].lazy=0;
    }
}
void update(int id)
{
	t[id].sum=(t[id<<1].sum+t[id<<1|1].sum)%mod;
}
void build(int id,int l,int r)
{
	t[id].l=l;
	t[id].r=r;
	if(l==r)
	{
		t[id].sum=tree[w[l]].num%mod;
		return;
	}
	int mid=(l+r)>>1;
	build(id<<1,l,mid);
	build(id<<1|1,mid+1,r);
	update(id);
}
void modify(int id,int x,int y,int z)
{
	int l=t[id].l,r=t[id].r;
	int mid=(l+r)>>1;
	if(x<=l&&r<=y)
	{
		t[id].lazy+=z%mod;
		t[id].sum+=z*(r-l+1)%mod;
		return;
	}
	pushdown(id);
	if(x<=mid)
	   modify(id<<1,x,y,z);
	if(y>mid)
	   modify(id<<1|1,x,y,z);
	update(id);
}
int query(int id,int x,int y)
{
	int l=t[id].l,r=t[id].r;
	int mid=(l+r)>>1;
	if(x<=l&&r<=y)
		return t[id].sum;
	pushdown(id);
	int ans=0;
	if(x<=mid)
	    ans+=query(id<<1,x,y)%mod;
	if(y>mid)
	    ans+=query(id<<1|1,x,y)%mod;
	return ans%mod;
}
void dfs1(int u,int f)
{
	tree[u].size=1;
	tree[u].deep=tree[f].deep+1;
	tree[u].fa=f;
	int maxsize=-1;
	for(int i=head[u];i!=-1;i=a[i].next)
	{
		int v=a[i].to;
		if(v==f)
		   continue;
		dfs1(v,u);
		tree[u].size+=tree[v].size;
		if(tree[v].size>maxsize)
		{
			maxsize=tree[v].size;
			tree[u].son=v;
		}
	}
}
void dfs2(int u,int t)
{
	tree[u].dfn=++cnt;
	tree[u].top=t;
	w[cnt]=u;
	if(!tree[u].son)
	   return;
	dfs2(tree[u].son,t);
	for(int i=head[u];i!=-1;i=a[i].next)
	{
		int v=a[i].to;
		if(v==tree[u].fa||v==tree[u].son)
			continue;
		dfs2(v,v);
	}
}
void add_son(int x,int z)
{
	modify(1,tree[x].dfn,tree[x].dfn+tree[x].size-1,z);
}
int query_son(int x)
{
	return query(1,tree[x].dfn,tree[x].dfn+tree[x].size-1)%mod;
}
void mchain(int x,int y,int z)
{
	z%=mod;
	while(tree[x].top!=tree[y].top)
	{
		if(tree[tree[x].top].deep< tree[tree[y].top].deep)
		    swap(x,y);
		modify(1,tree[tree[x].top].dfn,tree[x].dfn,z);
		x=tree[tree[x].top].fa;
	}
	if(tree[x].deep>tree[y].deep)
	    swap(x,y);
	modify(1,tree[x].dfn,tree[y].dfn,z);
}
int qchain(int x,int y)
{
	int res=0;
	while(tree[x].top!=tree[y].top)
	{
		if(tree[tree[x].top].deep<tree[tree[y].top].deep)
		    swap(x,y);
		res+=query(1,tree[tree[x].top].dfn,tree[x].dfn)%mod;
		x=tree[tree[x].top].fa;
	}
	if(tree[x].deep>tree[y].deep)
	    swap(x,y);
	res+=query(1,tree[x].dfn,tree[y].dfn)%mod;
	return res%mod;
}
signed main()
{
	memset(head,-1,sizeof(head));
	scanf("%lld%lld%lld%lld",&n,&m,&r,&mod);
	for(int i=1;i<=n;i++)
	   scanf("%lld",&tree[i].num);
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%lld%lld",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs1(r,r);
	dfs2(r,r);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int d,x,y,z;
		scanf("%lld",&d);
		if(d==1)
		   scanf("%lld%lld%lld",&x,&y,&z),mchain(x,y,z);
		if(d==2)
		   scanf("%lld%lld",&x,&y),printf("%lld\n",qchain(x,y)%mod);
		if(d==3)
		   scanf("%lld%lld",&x,&y),add_son(x,y);
		if(d==4)
		   scanf("%lld",&x),printf("%lld\n",query_son(x)%mod);
	}
	return 0;
}
2021/7/2 21:31
加载中...