萌新树剖70分求助,wa#2#9#10
查看原帖
萌新树剖70分求助,wa#2#9#10
153274
ignited楼主2021/8/26 18:12
#include<bits/stdc++.h>
#define MAXN 100010
#define ll long long
using namespace std;
ll n,m,r,p,cnt,mod;
ll top[MAXN],val[MAXN],dep[MAXN],son[MAXN],fa[MAXN],size[MAXN],a[MAXN],id[MAXN],tree[4*MAXN],tag[MAXN];
vector<ll> g[MAXN],child[MAXN];

void build(ll now,ll l,ll r)
{
	if(l==r)
	{
		tree[now]=val[l]%mod;
		return;
	}
	ll mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	tree[now]=(tree[now<<1]+tree[now<<1|1])%mod;
}

void pushdown(ll now,ll l,ll r)
{
	tag[now<<1]=(tag[now]+tag[now<<1])%mod;
	tag[now<<1|1]=(tag[now]+tag[now<<1|1])%mod;
	ll mid=(l+r)>>1;
	tree[now<<1]=(tree[now<<1]+(mid-l+1)*tag[now]%mod)%mod;
	tree[now<<1|1]=(tree[now<<1|1]+(r-mid)*tag[now]%mod)%mod;
	tag[now]=0;
}

void modify(ll now,ll l,ll r,ll ql,ll qr,ll v)
{
	//cout<<l<<"kkk"<<r<<' '<<ql<<' '<<qr<<endl;
	if(ql<=l&&qr>=r) 
	{
		tree[now]=(tree[now]+v*(r-l+1)%mod)%mod;
		tag[now]=(tag[now]+v)%mod;
		return;
	}
	pushdown(now,l,r);
	ll mid=(l+r)>>1;
	if(ql<=mid) modify(now<<1,l,mid,ql,qr,v);
	if(mid<qr) modify(now<<1|1,mid+1,r,ql,qr,v);
	tree[now]=(tree[now<<1]+tree[now<<1|1])%mod;
}

ll query(ll now,ll l,ll r,ll ql,ll qr)
{
	//cout<<l<<"kkk"<<r<<ql<<qr<<endl;
	if(ql<=l&&qr>=r) return tree[now];
	pushdown(now,l,r);
	ll mid=(l+r)>>1;
	ll ans=0;
	if(ql<=mid) ans=(ans+query(now<<1,l,mid,ql,qr))%mod;
	if(mid<qr) ans=(ans+query(now<<1|1,mid+1,r,ql,qr))%mod;
	return ans%mod;
}

void dfs1(ll u,ll y)
{
	dep[u]=dep[y]+1;
	size[u]=1;
	fa[u]=y;
	ll maxn=0; 
	for(ll i=0;i<g[u].size();i++)
	{
		ll v=g[u][i];
		if(v==y) continue;
		child[u].push_back(v);
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>maxn) son[u]=v,maxn=size[v];
	}
}

void dfs2(ll u,ll topf)
{
	id[u]=++cnt;
	val[cnt]=a[u];
	top[u]=topf;
	if(!son[u]) return;
	dfs2(son[u],topf);
	for(ll i=0;i<child[u].size();i++)
	{
		ll v=child[u][i];
		if(v!=son[u]) dfs2(v,v);
	}
}

ll query1(ll x,ll y)
{
	ll ans=0;
	while(top[x]!=top[y])
	{
		//cout<<x<<' '<<y<<' '<<top[x]<<' '<<top[y]<<endl;
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=(ans+query(1,1,n,id[top[x]],id[x]))%mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	//cout<<x<<y;
	ans=(ans+query(1,1,n,id[x],id[y]))%mod;
	return ans%mod;
}

ll query2(ll x)
{
	return query(1,1,n,id[x],id[x]+size[x]-1)%mod;
}

void modify1(ll x,ll y,ll v)
{
	ll ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		modify(1,1,n,id[top[x]],id[x],v);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	modify(1,1,n,id[x],id[y],v);
}

void modify2(ll x,ll v)
{
	modify(1,1,n,id[x],id[x]+size[x]-1,v);
}

int main()
{
	//freopen("P3384_1.in","r",stdin);
	//freopen("P3384","w",stdout); 
	cin>>n>>m>>r>>p;mod=p;
	for(ll i=1;i<=n;i++) cin>>a[i];
	for(ll i=1;i<n;i++)
	{
		ll u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(r,r);
	dfs2(r,r);
	build(1,1,n); 
	//for(ll i=1;i<=n;i++) cout<<fa[i]<<endl;
	for(ll i=1;i<=m;i++)
	{
		ll num,x,y,z;
		cin>>num;
		if(num==1)
		{
			cin>>x>>y>>z;
			modify1(x,y,z%mod);
		}
		if(num==2)
		{
			cin>>x>>y;
			cout<<query1(x,y)%mod<<endl;
		}
		if(num==3)
		{
			cin>>x>>z;
			modify2(x,z%mod);
		}
		if(num==4)
		{
			cin>>x;
			cout<<query2(x)%mod<<endl;
		}
	}
	return 0;
} 
2021/8/26 18:12
加载中...