萌新求助树剖
查看原帖
萌新求助树剖
394991
Sharing666楼主2021/7/10 10:05

样例过了,WA 1个点,RE 9个点

#include <bits/stdc++.h>
using namespace std;

long long n,m,mod,cnt,ans,num,root,sz[200002],val[200002],dep[200002],head[200002];
long long v[200002],id[200002],end[200002],top[200002],son[200002],fat[200002];

struct edge{
	int nxt,to;
}e[300002];

struct node{
	int lazy,sum;
}a[500002];

void addedge(int A,int B) {
	e[++cnt].to=B;
	e[cnt].nxt=head[A];
	head[A]=cnt;
}

void dfs1(int u,int last) {
	sz[u]=1;
	for(int i=head[u];i;i=e[i].nxt) {
		int v=e[i].to;
		if(v==last) continue;
		fat[v]=u;
		dep[v]=dep[u]+1;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>=sz[son[u]]) son[u]=v;
	}
}

void dfs2(int u,int last,int rt) {
	++num;
	top[u]=rt;
	id[u]=num;
	if(!son[u]) return; 
	dfs2(son[u],u,rt);
	end[son[u]]=num;
	for(int i=head[u];i;i=e[i].nxt) {
		int v=e[i].to;
		if(v==last || v==son[u]) continue;
		dfs2(v,u,v);
		end[v]=num;
	}
}

void pushup(int num) {
	a[num].sum=(a[num*2].sum+a[num*2+1].sum)%mod;
}

void pushdown(int num,int l,int r) {
	if(!a[num].lazy)return;
	a[num*2].lazy+=a[num].lazy;
	a[num*2+1].lazy+=a[num].lazy;
	a[num*2].lazy%=mod;
	a[num*2+1].lazy%=mod;
	int len;
	len=r-l+1;
	a[num*2].sum+=(len-(len>>1))*a[num].lazy;
	a[num*2+1].sum+=(len>>1)*a[num].lazy;
	a[num*2].sum%=mod;
	a[num*2+1].sum%=mod;
	a[num].lazy=0;
}

void build(int num,int l,int r) {
	if(l==r) {
		a[num].sum=v[l]%mod;
		return ;
	}
	int mid=(l+r)/2;
	build(num*2,l,mid);
	build(num*2+1,mid+1,r);
	pushup(num);
}

void update(int num,int l,int r,int ll,int rr,int x) {
	if(l>rr || ll>r) return ;
	if(ll<=l && r<=rr) {
		a[num].lazy+=x;
		a[num].sum+=((r-l+1)*x);
		return ;
	}
	pushdown(num,l,r);
	int mid=(l+r)/2;
	update(num*2,l,mid,ll,rr,x);
	update(num*2+1,mid+1,r,ll,rr,x);
	pushup(num);
}

long long query(int num,int l,int r,int ll,int rr) {
	if(l>rr || ll>r) return 0;
	if(ll<=l && rr<=r) return a[num].sum;
	pushdown(num,l,r);
	int mid=(l+r)/2;
	if(rr<=mid) return query(num*2,l,mid,ll,rr);
	if(ll>mid) return query(num*2+1,mid+1,r,ll,rr);
	return query(num*2,l,mid,ll,rr)+query(num*2+1,mid+1,r,ll,rr);
}

void lca(int x,int y,int z) {
	z%=mod;
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		if(z) update(1,1,n,id[top[x]],id[x],z);
		else ans+=query(1,1,n,id[top[x]],id[x]);
		x=fat[top[x]];
		ans%=mod;
	}
	if(dep[x]>dep[y]) swap(x,y);
	if(z) update(1,1,n,id[x],id[y],z);
	else ans+=query(1,1,n,id[x],id[y]);
	ans%=mod;
}

signed main() {
	scanf("%lld%lld%lld%lld",&n,&m,&root,&mod);
	for(int i=1;i<=n;i++) scanf("%lld",&val[i]);
	for(int i=1;i<=n-1;i++) {
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
		addedge(v,u);
	}
	dfs1((int)root,0);
	dfs2((int)root,0,root);
	end[root]=num;
	for(int i=1;i<=n;i++) v[id[i]]=val[i];
	build(1,1,n);
	while(m--) {
		int op,x,y,z;
		scanf("%d",&op);
		if(op==1) {
			scanf("%d%d%d",&x,&y,&z);
			lca(x,y,z);
		}
		if(op==2) {
			scanf("%d%d",&x,&y);
			ans=0;
			lca(x,y,0);
			printf("%lld\n",ans%mod);
		}
		if(op==3) {
			scanf("%d%d",&x,&y);
			update(1,1,(int)n,(int)id[x],(int)id[x]+sz[x]-1,y);
		}
		if(op==4) {
			scanf("%d",&x);
			printf("%lld\n",query(1,1,(int)n,(int)id[x],(int)id[x]+sz[x]-1)%mod);
		}
	}
	return 0;
}
2021/7/10 10:05
加载中...