萌新妹子刚学OI三天在线求调树剖线段树
查看原帖
萌新妹子刚学OI三天在线求调树剖线段树
556545
_anll_楼主2023/12/20 08:30

rt,本蒟蒻调试一个半小时,提交上去19pts,求dalao帮助

#include<iostream>
#define int long long
using namespace std;
struct Edge{
	int l,nxt;
}edges[200005];
struct Tr{
	int l,r,sum,laz;
}tr[800005];
int n,m,gen,mod,num[100005],tt,head[100005];
int son[100005],dep[100005],fas[100005],siz[100005];
int cnt,id[100005],val[100005],top[100005];
void add_edge(int f,int l){
	tt+=1;
	edges[tt]={l,head[f]};
	head[f]=tt;
}
void dfs1(int x,int fa){
	fas[x]=fa,siz[x]=1,dep[x]=dep[fa]+1;
	for(int i=head[x];i;i=edges[i].nxt){
		int l=edges[i].l;
		if(l==fa) continue;
		dfs1(l,x);
		siz[x]+=siz[l];
		if(siz[son[x]]<siz[l]) son[x]=l;
	}
}
void dfs2(int x,int t){
	top[x]=t,cnt+=1,id[x]=cnt,val[cnt]=num[x];
	if(!son[x]) return;
	dfs2(son[x],t);
	for(int i=head[x];i;i=edges[i].nxt){
		int l=edges[i].l;
		if(l==son[x]||l==fas[x]) continue;
		dfs2(l,l);
	}
}
void build(int p,int l,int r){
	tr[p].l=l,tr[p].r=r;
	if(l==r){
		tr[p].sum=val[l];
		return;
	}
	int m=(l+r)/2;
	build(p<<1,l,m);build((p<<1)+1,m+1,r);
	tr[p].sum=tr[p<<1].sum+tr[(p<<1)+1].sum;
}
void pushdown(int p){
	tr[p<<1].laz+=tr[p].laz;
	tr[p<<1].laz%=mod;
	tr[(p<<1)+1].laz+=tr[p].laz;
	tr[(p<<1)+1].laz%=mod;
	tr[p<<1].sum+=(tr[p<<1].r-tr[p<<1].l+1)*tr[p].laz;
	tr[p<<1].sum%=mod;
	tr[(p<<1)+1].sum+=(tr[(p<<1)+1].r-tr[(p<<1)+1].l+1)*tr[p].laz;
	tr[(p<<1)+1].sum%=mod;
	tr[p].laz=0;
}
int Find(int p,int l,int r){
	pushdown(p);
	if(l<=tr[p].l&&tr[p].r<=r) return tr[p].sum;
	int m=(tr[p].l+tr[p].r)/2,ok=0;
	if(l<=m) ok+=Find(p<<1,l,r);
	ok%=mod;
	if(m<r) ok+=Find((p<<1)+1,l,r);
	ok%=mod;
	return ok;
}
int Find_tr(int x,int y){
	int ok=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ok+=Find(1,id[top[x]],id[x]);
		ok%=mod;
		x=fas[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	ok+=Find(1,id[y],id[x]);
	ok%=mod;
	return ok;
}
int Find_son(int x){
	return Find(1,id[x],id[x]+siz[x]-1);
}
void update(int l,int r,int p,int k){
	if(l<=tr[p].l&&tr[p].r<=r){
		tr[p].laz+=k;
		tr[p].laz%=mod;
		tr[p].sum+=k*(tr[p].r-tr[p].l+1);
		tr[p].sum%=mod;
		return;
	}
	pushdown(p);
	int m=(tr[p].l+tr[p].r)/2;
	if(l<=m) update(l,r,p<<1,k);
	if(m<r) update(l,r,(p<<1)+1,k);
}
void update_tr(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(id[top[x]],id[x],1,k);
		x=fas[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	update(id[y],id[x],1,k);
}
void update_son(int x,int k){
	update(id[x],id[x]+siz[x]-1,1,k); 
} 
signed main(){
	int f,l;
	cin>>n>>m>>gen>>mod;
	for(int i=1;i<=n;i++) cin>>num[i];
	for(int i=1;i<n;i++){
		cin>>f>>l;
		add_edge(f,l);
		add_edge(l,f);
	}
	int op,x,y,z;
	dfs1(gen,0);dfs2(gen,gen);
	build(1,1,n);
	while(m--){
		cin>>op;
		if(op==1){
			cin>>x>>y>>z;
			update_tr(x,y,z);
		}
		else if(op==2){
			cin>>x>>y;
			cout<<Find_tr(x,y)%mod<<endl;
		}
		else if(op==3){
			cin>>x>>z;
			update_son(x,z);
		}
		else{
			cin>>x;
			cout<<Find_son(x)%mod<<endl;
		}
	}
	return 0;
}
2023/12/20 08:30
加载中...