Luogu_ P3384 【模板】轻重链剖分

#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct tree{ll v,late;}t[100010<<2];
int n,m,r,mod,val[100010],p[100010],size[100010],deep[100010],son[100010],top[100010];
int dfn[100010],tot,id[100010],cnt[100010];
vector<int> G[100010];

void make_tree(int u,int fa){
	size[u]=1;
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i];
		if(v==fa)continue;
		p[v]=u;
		deep[v]=deep[u]+1;
		make_tree(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]])son[u]=v;
	}
}

void make_son(int u,int fa){
	top[u]=fa;
	dfn[u]=++tot; id[tot]=u;
	if(son[u])make_son(son[u],fa);
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i];
		if(v!=p[u] && v!=son[u])make_son(v,v);
	}
	cnt[u]=tot;
}

void build_tree(int o,int l,int r){
	if(l==r){t[o].v=val[id[l]]; return;}
	int mid=l+r>>1;
	build_tree(o<<1,l,mid);
	build_tree(o<<1|1,mid+1,r);
	t[o].v=t[o<<1].v+t[o<<1|1].v;
}

void push_down(int o,int l,int r){
	t[o<<1].late+=t[o].late;
	t[o<<1|1].late+=t[o].late;
	int mid=l+r>>1;
	t[o<<1].v+=t[o].late*(mid-l+1);
	t[o<<1|1].v+=t[o].late*(r-mid);
	t[o].late=0; 
}

void update(int o,int l,int r,int L,int R,int v){
	if(L<=l && r<=R){
		t[o].late+=v;
		t[o].v+=(r-l+1)*v;
		return;
	}
	if(t[o].late)push_down(o,l,r);
	ll mid=l+r>>1;
	if(mid>=L)update(o<<1,l,mid,L,R,v);
	if(mid<R)update(o<<1|1,mid+1,r,L,R,v);
	t[o].v=t[o<<1].v+t[o<<1|1].v;
}

ll quire(int o,int l,int r,int L,int R){
	if(L<=l && r<=R)return t[o].v;
	if(t[o].late)push_down(o,l,r);
	int mid=l+r>>1;
	ll ans=0;
	if(L<=mid)ans+=quire(o<<1,l,mid,L,R);
	if(mid<R)ans+=quire(o<<1|1,mid+1,r,L,R);
	return ans;
}

void add(){
	int x,y,z;
	scanf("%d%d%d",&x,&y,&z);
	while(top[x]!=top[y]){
		if(deep[top[y]]>deep[top[x]])swap(x,y);
		update(1,1,tot,dfn[top[x]],dfn[x],z);
		x=p[top[x]];
	}
	if(deep[y]>deep[x])swap(x,y);
	update(1,1,tot,dfn[y],dfn[x],z);
}

void get_answer(){
	int x,y;
	ll ans=0;
	scanf("%d%d",&x,&y);
	while(top[x]!=top[y]){
		if(deep[top[y]]>deep[top[x]])swap(x,y);
		ans+=quire(1,1,tot,dfn[top[x]],dfn[x]);
		ans%=mod;
		x=p[top[x]];
	}
	if(deep[y]>deep[x])swap(x,y);
	ans+=quire(1,1,tot,dfn[y],dfn[x]);
	printf("%lld
",ans%mod);
}

void add_son(){
	int x,z;
	scanf("%d%d",&x,&z);
	update(1,1,tot,dfn[x],cnt[x],z);
}

void get_son(){
	int x;
	scanf("%d",&x);
	ll ans=quire(1,1,tot,dfn[x],cnt[x]);
	printf("%lld
",ans%mod);
}

int main(){
	scanf("%d%d%d%d",&n,&m,&r,&mod);
	for(int i=1;i<=n;i++)scanf("%d",&val[i]);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	p[r]=r;
	make_tree(r,r);
	make_son(r,r);
	build_tree(1,1,tot);
	while(m--){
		int q;
		scanf("%d",&q);
		if(q==1)add();
		if(q==2)get_answer();
		if(q==3)add_son();
		if(q==4)get_son();
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/codetogether/p/13504285.html