蒟蒻树剖爆RE,求助
查看原帖
蒟蒻树剖爆RE,求助
133226
a_bottle楼主2020/6/7 21:11

rt 好像是线段树区间加有问题 也可能不是

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read()
{
	ll x=0,q=1;
	char ch=getchar();
	while(ch>'9'||ch<'0')
	{
		if(ch=='-')q=-1;
		ch=getchar();
	}	
	while(ch>='0'&&ch<='9')
	{
		x=(x<<3)+(x<<1)+ch-'0';
		ch=getchar();
	}
	return x*q;
}
const int maxn=1e5+6;
int n,m,r,mod,cnt;
int fa[maxn],dep[maxn],siz[maxn],son[maxn],id[maxn],top[maxn],rev[maxn];
ll t[maxn],w[maxn],a[maxn];
int laz[maxn];
vector<int >g[maxn];
inline void dfs1(int x,int f)
{
	fa[x]=f;
	dep[x]=dep[fa[x]]+1;
	siz[x]=1;
	for(register int i=0;i<g[x].size();i++)
	{
		int y=g[x][i];
		if(y==f)continue;
		dfs1(y,x);
		siz[x]+=siz[y];
		if(siz[y]>siz[son[x]])
		son[x]=y;
	}
}
inline void dfs2(int x,int topf)
{
	id[x]=++cnt;
	rev[cnt]=x;
	w[cnt]=a[x];
	top[x]=topf;
	if(!son[x])return;
	dfs2(son[x],topf);
	for(register int i=0;i<g[x].size();i++)
	{
		int y=g[x][i];
		if(y==fa[x]||y==son[x])continue;
		dfs2(y,y);
	}
}
inline void build(int x,int l,int r)
{
	if(l==r)
	{
		t[x]=w[l]%mod;
		return;
	}
	int mid=(l+r)>>1;
	build(x<<1,l,mid);
	build((x<<1)|1,mid+1,r);
	t[x]=(t[x<<1]+t[(x<<1)|1])%mod;
}
inline void pushdown(int x,int l,int r)
{
	int mid=(l+r)>>1;
	t[x<<1]+=(mid-l+1)*laz[x];
	t[(x<<1)|1]+=(r-mid)*laz[x];
	t[x<<1]%=mod;
	t[(x<<1)|1]%=mod;
	laz[x<<1]+=laz[x];
	laz[(x<<1)]+=laz[x];
	laz[x]=0;
}
inline void add(int l,int r,int y,int lx,int rx,int x)
{
	if(l<=lx&&r>=rx)
	{
		t[x]+=(rx-lx+1)*y;
		laz[x]+=y;
		t[x]%=mod;
		laz[x]%=mod;
	}
	int mid=(lx+rx)>>1;
	if(laz[x]&&lx!=rx)
	pushdown(x,lx,rx);
	if(l<=mid)
	add(l,r,y,lx,mid,x<<1);
	if(r>mid)
	add(l,r,y,mid+1,rx,(x<<1)|1);
	t[x]=(t[x<<1]+t[(x<<1)|1])%mod;
}
inline ll ask(int l,int r,int lx,int rx,int x)
{
	if(l<=lx&&r>=rx)
	return t[x];
	int mid=(lx+rx)>>1;
	if(laz[x]&&lx!=rx)
	pushdown(x,lx,rx);
	ll sum=0;
	if(l<=mid)
	sum+=ask(l,r,lx,mid,x<<1);
	sum%=mod;
	if(r>mid)
	sum+=ask(l,r,mid+1,rx,(x<<1)|1);
	sum%=mod;
	return sum;
}
inline void addpath(int x,int y,int z)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		add(id[top[x]],id[x],z,1,n,1);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	add(id[x],id[y],z,1,n,1);
}
inline void addson(int x,int y)
{
	add(id[x],id[x]+siz[x]-1,y,1,n,1);
}
inline ll askpath(int x,int y)
{
	ll ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ans+=ask(id[top[x]],id[x],1,n,1);
		ans%=mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans+=ask(id[x],id[y],1,n,1);
	ans%=mod;
	return ans;
}
inline ll askson(int x)
{
	ll ans=0;
	ans=ask(id[x],id[x]+siz[x]-1,1,n,1);
	return ans;
}
int main()
{
	n=read(),m=read(),r=read(),mod=read();
	for(register int i=1;i<=n;i++)
	a[i]=read();
	for(register int i=1;i<n;i++)
	{
		int x,y;
		x=read(),y=read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs1(r,0);
	dfs2(r,r);
	build(1,1,n);
	while(m--)
	{
		int opt,x,y,z;
		opt=read();
		if(opt==1)
		{
			x=read(),y=read(),z=read(),z%=mod;
			addpath(x,y,z);
		}
		if(opt==2)
		{
			x=read(),y=read();
			cout<<askpath(x,y)<<endl;
		}
		if(opt==3)
		{
			x=read(),y=read(),y%=mod;
			addson(x,y);
		}
		if(opt==4)
		{
			x=read();
			cout<<askson(x)<<endl;
		}
	}
	return 0;
}
2020/6/7 21:11
加载中...