蒟蒻70pts求助
查看原帖
蒟蒻70pts求助
264867
某珂学的超OIer楼主2020/12/12 14:18

一直找不出 bugbug请不要嫌弃蒟蒻的马蜂

#include<cstdio>
#include<vector>
#include<cstdlib>
#define int long long
using namespace std;
int n,m,root,MOD;
int tot;
int a[100001];
int w[100001];
int id[10001];
int sz[100001];
int fa[100001];
int top[100001];
int son[100001];
int dep[100001];
int Tag[100001<<2],c[100001<<2];
vector<int> G[100001];
void build(int o,int l,int r)
{
	if(l==r)
	{
		c[o]=w[l];
		c[o]%=MOD;
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	c[o]=c[o<<1]+c[o<<1|1];
	c[o]%=MOD;
}
void addTag(int o,int l,int r,int v)
{
	Tag[o]+=v;
	c[o]+=(r-l+1)*v;
	c[o]%=MOD;
}
void downTag(int o,int l,int r,int mid)
{
	if(Tag[o]==0)
	{
		return;
	}
	addTag(o<<1,l,mid,Tag[o]);
	addTag(o<<1|1,mid+1,r,Tag[o]);
	Tag[o]=0;
}
int query_tree(int o,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)
	{
		return c[o];
	}
	if(l>y||r<x)
	{
		return 0;
	}
	int mid=(l+r)>>1;
	downTag(o,l,r,mid);
	int left=query_tree(o<<1,l,mid,x,y);
	int right=query_tree(o<<1|1,mid+1,r,x,y);
	return (left+right)%MOD;
}
void update_tree(int o,int l,int r,int x,int y,int v)
{
	if(x<=l&&r<=y)
	{
		addTag(o,l,r,v);
		return;
	}
	if(l>y||r<x)
	{
		return;
	}
	int mid=(l+r)>>1;
	downTag(o,l,r,mid);
	update_tree(o<<1,l,mid,x,y,v);
	update_tree(o<<1|1,mid+1,r,x,y,v);
	c[o]=c[o<<1]+c[o<<1|1];
	c[o]%=MOD;
}
void Swap(int &x,int &y)
{
	int temp=x;
	x=y;
	y=temp;
}
void dfs_first(int u,int father)
{
	sz[u]=1;
	fa[u]=father;
	int max_son_sz=-1;
	dep[u]=dep[father]+1;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(v==father)
		{
			continue;
		}
		dfs_first(v,u);
		sz[u]+=sz[v];
		if(sz[v]>max_son_sz)
		{
			son[u]=v;
			max_son_sz=sz[v];
		}
	}
}
void dfs_second(int u,int top_of_u)
{
	id[u]=++tot;
	w[id[u]]=a[u];
	top[u]=top_of_u;
	if(son[u]==0)
	{
		return;
	}
	dfs_second(son[u],top_of_u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(v==fa[u]||v==son[u])
		{
			continue;
		}
		dfs_second(v,v);
	}
}
int query_son(int x)
{
	return query_tree(1,1,n,id[x],id[x]+sz[x]-1)%MOD;
}
int query_road(int x,int y)
{
	int res=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		{
			Swap(x,y);
		}
		res+=query_tree(1,1,n,id[top[x]],id[x]);
		res%=MOD;
		x=top[x];
		x=fa[x];
	}
	if(dep[x]>dep[y])
	{
		Swap(x,y);
	}
	res+=query_tree(1,1,n,id[x],id[y]);
	res%=MOD;
	return res;
}
void update_son(int x,int v)
{
	v%=MOD;
	update_tree(1,1,n,id[x],id[x]+sz[x]-1,v);
}
void update_road(int x,int y,int v)
{
	v%=MOD;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		{
			Swap(x,y);
		}
		update_tree(1,1,n,id[top[x]],id[x],v);
		x=top[x];
		x=fa[x];
	}
	if(dep[x]>dep[y])
	{
		Swap(x,y);
	}
	update_tree(1,1,n,id[x],id[y],v);
}
signed main()
{
	scanf("%lld%lld%lld%lld",&n,&m,&root,&MOD);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
	}
	for(int i=1;i<=n-1;i++)
	{
		int u,v;
		scanf("%lld%lld",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs_first(root,0);
	dfs_second(root,root);
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int opt,x,y,v;
		scanf("%lld",&opt);
		if(opt==1)
		{
			scanf("%lld%lld%lld",&x,&y,&v);
			update_road(x,y,v);
		}
		else if(opt==2)
		{
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query_road(x,y));
		}
		else if(opt==3)
		{
			scanf("%lld%lld",&x,&v);
			update_son(x,v);
		}
		else
		{
			scanf("%lld",&x);
			printf("%lld\n",query_son(x));
		}
	}
	return 0;
}
2020/12/12 14:18
加载中...