求助树剖板子
查看原帖
求助树剖板子
401052
Endline楼主2022/1/20 14:51

RT,在 #2 RE了

#include<bits/stdc++.h>
#define MAXN 100002
#define ls(x) 2*x
#define rs(x) 2*x+1
using namespace std;
inline int read()
{
	int f=1,w=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
	return f*w;
}
int n,m,r,mod;
vector<int>V[MAXN];
int siz[MAXN],dep[MAXN],fa[MAXN],son[MAXN],w[MAXN],a[MAXN],top[MAXN],dfn[MAXN],num;
int tr[MAXN],tag[MAXN];
void add(int x,int y)
{
	V[x].push_back(y);
	return;
}
void dfs1(int now,int f,int deep)
{
	dep[now]=deep;
	fa[now]=f;
	siz[now]=1;
	int son_siz=-1;
	for(int i:V[now])
	{
		int t=i;
		if(t==f)continue;
		dfs1(t,now,deep+1);
		siz[now]+=siz[t];
		if(siz[t]>son_siz)son[now]=t,son_siz=siz[t];
	}
	return;
}
void dfs2(int now,int topn)
{
	dfn[now]=++num;
	w[num]=a[now];
	top[now]=topn;
	if(!son[now])return;
	dfs2(son[now],topn);
	for(int i:V[now])
	{
		int t=i;
		if(t==fa[now]||t==son[now])continue;
		dfs2(t,t);
	}
}
void push_up(int p)
{
	tr[p]=(tr[ls(p)]+tr[rs(p)])%mod;
}
void addtag(int l,int r,int p,int k)
{
	tr[p]+=(r-l+1)*k;
	tag[p]+=k;
	tr[p]%=mod;
	tag[p]%=mod;
}
void push_down(int l,int r,int p)
{
	if(tag[p])
	{
		int mid=(l+r)>>1;
		addtag(l,mid,ls(p),tag[p]);
		addtag(mid+1,r,rs(p),tag[p]);
		tag[p]=0;
	}
}
void build(int l,int r,int p)
{
	if(l==r)
	{
		tr[p]=w[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(p));build(mid+1,r,rs(p));
	push_up(p);
}
void update(int l,int r,int s,int t,int p,int k)
{
	k%=mod;
	if(s>=l&&t<=r)
	{
		addtag(s,t,p,k);
		return;
	}
	push_down(s,t,p);
	int mid=(s+t)>>1;
	if(mid>=l)update(l,r,s,mid,ls(p),k);
	if(mid<r)update(l,r,mid+1,t,rs(p),k);
	push_up(p);
	return;
}
int query(int l,int r,int s,int t,int p)
{
	if(s>=l&&t<=r)
		return tr[p]%mod;
	push_down(s,t,p);
	int mid=(s+t)>>1,sum=0;
	if(mid>=l)sum+=query(l,r,s,mid,ls(p));
	if(mid<r)sum+=query(l,r,mid+1,t,rs(p));
	return sum%mod;
}
int ask_range(int s,int t)
{
	int ans=0;
	while(top[s]!=top[t])
	{
		if(dep[top[s]]<dep[top[t]])swap(s,t);
		ans+=query(dfn[top[s]],dfn[s],1,n,1);
		ans%=mod;
		s=fa[top[s]];
	}
	if(dep[s]>dep[t])swap(s,t);
	ans+=query(dfn[s],dfn[t],1,n,1);
	return ans;
}
int ask_son(int s)
{
	return query(dfn[s],dfn[s]+siz[s]-1,1,n,1);
}
void upd_range(int s,int t,int k)
{
	k%=mod;
	while(top[s]!=top[t])
	{
		if(dep[top[s]]<dep[top[t]])swap(s,t);
		update(dfn[top[s]],dfn[s],1,n,1,k);
		s=fa[top[s]];
	}
	if(dep[s]>dep[t])swap(s,t);
	update(dfn[s],dfn[t],1,n,1,k);
	return;
}
void upd_son(int s,int k)
{
	k%=mod;
	update(dfn[s],dfn[s]+siz[s]-1,1,n,1,k);
	return;
}
int main()
{
	freopen("P3384_2.in","r",stdin);
	freopen("a.out","w",stdout);
	n=read(),m=read(),r=read(),mod=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	for(int i=1;i<n;i++)
	{
		int x=read(),y=read();
		add(x,y);add(y,x);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,n,1);
	for(int i=1;i<=m;i++)
	{
		int opt=read(),x=read(),y,z;
		switch(opt)
		{
			case 1:
				y=read(),z=read();
				upd_range(x,y,z);
				break;
			case 2:
				y=read();
				cout<<ask_range(x,y)<<endl;
				break;
			case 3:
				z=read();
				upd_son(x,z);
				break;
			case 4:
				cout<<ask_son(x)<<endl;
				break;
			default:
				break;
		}
	}
    return 0;
}
2022/1/20 14:51
加载中...