P3384树链剖分wa73分求助玄关!
  • 板块灌水区
  • 楼主ChenZQ
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/1/13 10:06
  • 上次更新2025/1/13 15:28:38
查看原帖
P3384树链剖分wa73分求助玄关!
745358
ChenZQ楼主2025/1/13 10:06

已经调两天了。。。求助!

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 400010;
int n,m,r,p;
int a[N];
int h[N],e[N],ne[N],idx,id[N],sz[N];
int bs[N],fa[N],tp[N],w[N],dep[N],tag[N],seg[N],cnt=0;
void dfs(int u,int f)
{
	dep[u]=dep[f]+1;
	fa[u]=f;
	int mx=0,idd=0;sz[u]=1; 
	for(int i=h[u];i!=-1;i=ne[i])
	{
		if(e[i]!=f)
		{
			dfs(e[i],u);
			sz[u]+=sz[e[i]];
			if(sz[e[i]]>mx) mx=sz[e[i]],idd=e[i];
		}
	}
	bs[u]=idd;
}
void dfs2(int u,int f,int top)
{
	id[u]=++cnt;tp[u]=top;
	w[cnt]=a[u];
	if(bs[u])dfs2(bs[u],u,top);
	for(int i=h[u];i!=-1;i=ne[i])
	{
		if(e[i]!=f && e[i]!=bs[u]) dfs2(e[i],u,e[i]);
	}
}
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void build(int l,int r,int u)
{
	if(l==r) 
	{
		seg[u]=w[l];
		seg[u]%=p;
		return;
	}
	int mid=(l+r)>>1;build(l,mid,u<<1);build(mid+1,r,u<<1|1);
	seg[u]=(seg[u<<1]+seg[u<<1|1])%p;
}
void pd(int u,int l,int r)
{
	int mid=(l+r)>>1;
	seg[u<<1]+=(mid-l+1)*tag[u]%p;seg[u<<1|1]+=(r-mid)*tag[u]%p;
	tag[u<<1]+=tag[u];tag[u<<1|1]+=tag[u];tag[u]=0;
	seg[u<<1]%=p;seg[u<<1|1]%=p;
}
void update(int l,int r,int ll,int rr,int u,int w)
{
	if(l>=ll && r<=rr)
	{
		tag[u]+=w;seg[u]+=(r-l+1)*w%p;seg[u]%=p; tag[u]%=p;
		pd(u,l,r);
		return;
	}
	pd(u,l,r);int mid=(l+r)>>1;
	if(mid>=ll)update(l,mid,ll,rr,u<<1,w);
	if(mid<rr)update(mid+1,r,ll,rr,u<<1|1,w);
	seg[u]=seg[u<<1]+seg[u<<1|1];
	seg[u]%=p;                                                           
}
int query(int l,int r,int ll,int rr,int u)
{
	if(l>=ll && r<=rr) return seg[u];
	pd(u,l,r);
	int mid=(l+r)>>1;
	int ans=0;
	if(mid>=ll) ans+=query(l,mid,ll,rr,u<<1);
	if(mid<rr) ans+=query(mid+1,r,ll,rr,u<<1|1);
	ans%=p;
	return ans;
}
void updw(int x,int y,int z)
{
	while(tp[x]!=tp[y])
	{
		if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
		update(1,n,id[tp[x]],id[x],1,z%p);
		x=fa[tp[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	update(1,n,id[x],id[y],1,z);
}
void qudw(int x,int y)
{
	int ans=0;
	while(tp[x]!=tp[y])
	{
		if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
		ans+=query(1,n,id[tp[x]],id[x],1);
		ans%=p;
		x=fa[tp[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans+=query(1,n,id[x],id[y],1);
	ans%=p;
	printf("%lld\n",ans);
}
signed main()
{
	scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	memset(h,-1,sizeof h);
	for(int i=1;i<=n-1;i++)
	{
		int a,b;scanf("%lld%lld",&a,&b);
		add(a,b);add(b,a);
	}
	dfs(r,0);
	dfs2(r,r,r);
	build(1,n,1);
	for(int i=1;i<=m;i++)
	{
		int op,x,y,z;
		scanf("%lld",&op);
		if(op==1)
		{
			scanf("%lld%lld%lld",&x,&y,&z);
			updw(x,y,z%p);
		}
		else if(op==2)
		{
			scanf("%lld%lld",&x,&y);qudw(x,y);
		}
		else if(op==3)
		{
			scanf("%lld%lld",&x,&z);
			update(1,n,id[x],id[x]+sz[x]-1,1,z%p);
		}
		else
		{
			scanf("%lld",&x);
			printf("%lld\n",query(1,n,id[x],id[x]+sz[x]-1,1));
		}
	}
}
2025/1/13 10:06
加载中...