树剖模板 WA+RE 37pts 求调 码风良好
查看原帖
树剖模板 WA+RE 37pts 求调 码风良好
572133
潘德理2010楼主2024/9/3 13:25
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct sgt{
	ll s[400010],t[400010],p;
	void m(ll &x){
		x=(x%p+p)%p;
	}
	void f(ll u,ll le,ll ri,ll v){
		s[u]+=v*(ri-le+1);
		t[u]+=v;
		m(s[u]),m(t[u]);
	}
	void push_down(ll u,ll le,ll ri){
		ll mid=(le+ri)/2;
		f(2*u,le,mid,t[u]);
		f(2*u+1,mid+1,ri,t[u]);
		t[u]=0;
	}
	void push_up(ll u){
		s[u]=s[2*u]+s[2*u+1];
		m(s[u]);
	}
	void add(ll u,ll le,ll ri,ll x,ll y,ll v){
		if(x<=le&&ri<=y){
			f(u,le,ri,v);
			return ;
		}
		push_down(u,le,ri);
		ll mid=(le+ri)/2;
		if(x<=mid) add(2*u,le,mid,x,y,v);
		if(y>mid) add(2*u+1,mid+1,ri,x,y,v);
		push_up(u);
	}
	ll que(ll u,ll le,ll ri,ll x,ll y){
		push_down(u,le,ri);
		if(x<=le&&ri<=y){
			return s[u];
		}
		ll mid=(le+ri)/2;
		ll res=0;
		if(x<=mid) res+=que(2*u,le,mid,x,y);
		if(y>mid) res+=que(2*u+1,mid+1,ri,x,y);
		m(res);
		return res;
	}
}t;
ll n,m,r,p,op,a,b,c,s[100010];
ll d[100010],f[100010],id[100010],h[100010],top[100010],sz[100010],cnt;
vector<ll> e[100010];
void dfs1(ll u,ll fa){
	sz[u]=1;
	d[u]=d[fa]+1;
	f[u]=fa;
	id[u]=++cnt;
	for(ll i=0;i<ll(e[u].size());i++){
		ll v=e[u][i];
		if(v==fa) continue; 
		dfs1(v,u);
		sz[u]+=sz[v];
	}
}
void dfs2(ll u,ll fi){
	top[u]=fi;
	ll hs=0;
	for(ll i=0;i<ll(e[u].size());i++){
		ll v=e[u][i];
		if(v!=f[u]&&sz[hs]<sz[v]){
			hs=v;
		}
	}
	if(!hs) return ;
	dfs2(hs,fi);
	for(ll i=0;i<ll(e[u].size());i++){
		ll v=e[u][i];
		if(v!=f[u]&&v!=hs){
			dfs2(v,v);
		}
	}
	h[u]=hs;
}
void add_p(ll u,ll v,ll w){
	while(top[u]!=top[v]){
		if(d[top[u]]<d[top[v]]) swap(u,v);
		t.add(1,1,n,id[top[u]],id[u],w);
		u=f[top[u]];
	}
	if(d[u]>d[v]) swap(u,v);
	t.add(1,1,n,id[u],id[v],w);
}
ll que_p(ll u,ll v){
	ll res=0;
	while(top[u]!=top[v]){
		if(d[top[u]]<d[top[v]]) swap(u,v);
		res+=t.que(1,1,n,id[top[u]],id[u]);
		res%=p;
		u=f[top[u]];
	}
	if(d[u]>d[v]) swap(u,v);
	res+=t.que(1,1,n,id[u],id[v]);
	return res;
}
void add_s(ll u,ll w){
	t.add(1,1,n,id[u],id[u]+sz[u]-1,w);
}
ll que_s(ll u){
	return t.que(1,1,n,id[u],id[u]+sz[u]-1);
}
int main(){
	scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
	t.p=p;
	for(int i=1;i<=n;i++){
		scanf("%lld",&s[i]);
	}
	for(int i=1;i<n;i++){
		scanf("%lld%lld",&a,&b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	dfs1(r,0);
	dfs2(r,r);
	for(int i=1;i<=n;i++){
		t.add(1,1,n,id[i],id[i],s[i]);
	}
	while(m--){
		scanf("%lld%lld",&op,&a);
		if(op==1){
			scanf("%lld%lld",&b,&c);
			add_p(a,b,c);
		}
		if(op==2){
			scanf("%lld",&b);
			printf("%lld\n",que_p(a,b)%p);
		}
		if(op==3){
			scanf("%lld",&b);
			add_s(a,b);
		}
		if(op==4){
			printf("%lld\n",que_s(a)%p);
		}
	}
}
2024/9/3 13:25
加载中...