萌新妹子 学树剖 0.00005second 只A了第二个点求调
查看原帖
萌新妹子 学树剖 0.00005second 只A了第二个点求调
524801
不食嗟来之食楼主2022/9/11 00:09
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
#define lson k<<1
#define rson k<<1|1
const int N=2e6+5;
struct tre{
	int l,r,w,size,f;
}T[N];
int mod;
vector<int> e[N];
int n,m,root,dep[N],fa[N],son[N],tot[N],top[N],idx[N];
int val[N],cnt,a[N],b[N];
int dfs1(int u,int f,int deep)
{
	dep[u]=deep;
	fa[u]=f;
	tot[u]=1;
	int maxson=-1;
	for(auto v:e[u])
	{
		if(v==f) continue;
		tot[u]+=dfs1(v,u,deep+1);
		if(tot[v]>maxson)
		{
			maxson=tot[v];
			son[u]=v;
		}
	}
	return tot[u];
}
void dfs2(int now,int topf)
{
	idx[now]=++cnt;
	a[cnt]=b[now];
	top[now]=topf;
	if(!son[now])
	{
		return ;
	}
	dfs2(son[now],topf);
	for(auto v:e[now])
	{
		if(!idx[v])
		{
			dfs2(v,v);
		}
	}
	return ;
}
void push_up(int k)
{
	T[k].w=(T[lson].w+T[rson].w+mod)%mod;
	return ;
}
void build(int k,int l,int r)
{
	T[k].l=l,T[k].r=r;
	T[k].size=r-l+1;
	if(l==r)
	{
		T[k].w=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	push_up(k);
	return ;
}
void push_down(int k)
{
	if(T[k].f)
	{
		T[lson].w=(T[lson].w+T[lson].size*T[k].f)%mod;
		T[rson].w=(T[rson].w+T[rson].size*T[k].f)%mod;
		T[lson].f=(T[k].f+T[lson].f)%mod;
		T[rson].f=(T[k].f+T[rson].f)%mod;
		T[k].f=0;
	}
	return ;
}
void Inadd(int k,int l,int r,int val)
{
	if(l<=T[k].l&&r>=T[k].r)
	{
		T[k].w+=T[k].size*val;
		T[k].f+=val;
		return ;
	}
	push_down(k);
	int mid=(T[k].l+T[k].r)>>1;
	if(l<=mid)
	{
		Inadd(lson,l,r,val);
	}
	if(r>mid)
	{
		Inadd(rson,l,r,val);
	}
	push_up(k);
	return ;
}
void Treeadd(int x,int y,int val)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]<dep[top[y]]])
		{
			swap(x,y);
		}
		Inadd(1,idx[top[x]],idx[x],val);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	Inadd(1,idx[x],idx[y],val);
	return ;
}
int Insum(int k,int l,int r)
{
	int ans=0;
	if(l<=T[k].l&&r>=T[k].r)
	{
		return T[k].w;
	}
	push_down(k);
	int mid=(T[k].l+T[k].r)>>1;
	if(l<=mid)
	{
		ans=(ans+Insum(lson,l,r))%mod;
	}
	if(r>mid)
	{
		ans=(ans+Insum(rson,l,r))%mod;
	}
	return ans;
}
void Treesum(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=(ans+Insum(1,idx[top[x]],idx[x]))%mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans=(ans+Insum(1,idx[x],idx[y]))%mod;
	printf("%d\n",ans);
	return ;
}
int main()
{
//	freopen("P3384_1.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&root,&mod);
	for(int i=1;i<=n;i++) scanf("%d",&b[i]);
	for(int i=1;i<=n-1;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(root,0,1);
	dfs2(root,root);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int opt,x,y,z;
		scanf("%d",&opt);
		switch(opt)
		{
			case 1:{
				scanf("%d%d%d",&x,&y,&z);
				Treeadd(x,y,z);
				break;
			}
			case 2:{
				scanf("%d%d",&x,&y);
				Treesum(x,y);
				break;
			}
			case 3:{
				scanf("%d%d",&x,&z);
				Inadd(1,idx[x],idx[x]+tot[x]-1,z%mod);
				break;
			}
			case 4:{
				scanf("%d",&x);
				printf("%d\n",Insum(1,idx[x],idx[x]+tot[x]-1));
				break;
			}
		}
	}
	return 0;
}

2022/9/11 00:09
加载中...