树链剖分模板WA求助
查看原帖
树链剖分模板WA求助
421265
eastcloud楼主2022/6/29 20:32
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int mod,tot;
int val[100001],siz[100001],son[100001],fa[100001],dep[100001];
int num[100001],top[100001],nval[100001];
vector<int> l[100001];
struct Node{
	int val,add,l,r;
	#define v(x) tr[x].val
	#define d(x) tr[x].add
	#define l(x) tr[x].l
	#define r(x) tr[x].r
}tr[400001];
void build(int x,int l,int r){
	l(x)=l;
	r(x)=r;
	if(l==r){
		v(x)=nval[l];
		return;
	}
	int mid=(l+r)>>1;
	build(2*x,l,mid);
	build(2*x+1,mid+1,r);
	v(x)=(v(2*x)+v(x*2+1))%mod;
	//cout<<x<<' '<<' '<<l(x)<<' '<<r(x)<<' '<<v(x)<<endl;
}
void push_down(int x){
	if(d(x)){
		v(x*2)=(v(x*2)+d(x)*(r(x*2)-l(x*2)+1));
		v(x*2+1)=(v(x*2+1)+d(x)*(r(x*2+1)-l(x*2+1)+1));
		d(x*2)+=d(x);
		d(x*2+1)+=d(x);
		d(x)=0;
	}
}
void change(int x,int l,int r,int v){
	if(l(x)>=l && r(x)<=r){
		v(x)=(v(x)+v*(r-l+1))%mod;
		d(x)+=v;
		return;
	}
	push_down(x);
	int mid=(l(x)+r(x))>>1;
	if(l<=mid) change(x*2,l,r,v);
	if(r>mid) change(x*2+1,l,r,v);
	v(x)=(v(2*x)+v(x*2+1))%mod;
}
int query(int x,int l,int r){
	if(l(x)>=l && r(x)<=r)return v(x);
	push_down(x);
	int ans=0,mid=(l(x)+r(x))>>1;
	if(l<=mid) ans+=query(x*2,l,r);
	if(r>mid) ans+=query(x*2+1,l,r);
	return ans%mod;
}
void dfs1(int x,int root,int d){
	siz[x]++;
	fa[x]=root;
	dep[x]=d;
	for(int i=0;i<l[x].size();i++){
		int u=l[x][i];
		if(u==root) continue;
		dfs1(u,x,d+1);
		siz[x]+=siz[u];
		if(siz[u]>siz[son[x]]) son[x]=u;
	}
}
void dfs2(int x,int topx){
	num[x]=++tot;
	nval[tot]=val[x];
	top[x]=topx;
	if(!son[x]) return;
	dfs2(son[x],topx);
	for(int i=0;i<l[x].size();i++){
		int u=l[x][i];
		if(u==son[x] || u==fa[x]) continue;
		dfs2(u,u);
	}
}
void updroad(int u,int v,int x){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		change(1,num[top[u]],num[u],x);
		u=fa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	change(1,num[u],num[v],x);
}
int queryroad(int u,int v){
	int ans=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		ans=(ans+query(1,num[u],num[top[u]]))%mod;
		u=fa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	ans=(ans+query(1,num[u],num[v]))%mod;
	return ans;
}
int main(){
	int n,u,v,x,jud,m,root;
	cin>>n>>m>>root>>mod;
	for(int i=1;i<=n;i++){
		cin>>val[i];
		val[i]=val[i]%mod;
	}
	for(int i=1;i<=n-1;i++){
		cin>>u>>v;
		l[u].push_back(v);
		l[v].push_back(u);
	}
	dfs1(root,0,1);
	dfs2(root,root);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		cin>>jud;
		if(jud==1){
			cin>>u>>v>>x;
			updroad(u,v,x);
		}
		if(jud==2){
			cin>>u>>v;
			cout<<queryroad(u,v)<<endl;
		}
		if(jud==3){
			cin>>u>>x;
			change(1,num[u],num[u]+siz[u]-1,x);
		}
		if(jud==4){
			cin>>u;
			cout<<query(1,num[u],num[u]+siz[u]-1)<<endl;
		}
	}
}
2022/6/29 20:32
加载中...