树剖模板求调,悬棺
  • 板块学术版
  • 楼主CangerYumo
  • 当前回复7
  • 已保存回复7
  • 发布时间2024/3/4 19:43
  • 上次更新2024/3/4 21:38:29
查看原帖
树剖模板求调,悬棺
847286
CangerYumo楼主2024/3/4 19:43
#include<bits/stdc++.h>
#define int long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
int mod,n,m,rt,p,x,y,r,e,s,op,cnt;
int a[100005],wson[100005],dep[100005],fa[100005],siz[100005],id[100005];
int wei[100005];//new id's weight
int top[100005];//the top of each chain
int sum[100005],tag[100005];//segment tree
int en[100005];
bool vis[100005];vector<int> t[100005];
void dfs1(int now,int dept,int fat){
	vis[now]=1;siz[now]=1;dep[now]=dept;fa[now]=fat;
	int w=0;
	for(int i=0;i<t[now].size();i++){
		if(vis[t[now][i]]) continue;
		dfs1(t[now][i],dept+1,now);
		siz[now]+=siz[t[now][i]];
		if(w<siz[t[now][i]]){
			w=siz[t[now][i]];
			wson[now]=t[now][i];
		}
	}return;
}
void dfs2(int now,int rt){
	//cout<<now<<' ';
	vis[now]=1;
	id[now]=++cnt;
	en[cnt]=now;
	wei[cnt]=a[now];
	top[now]=rt;
	if(!wson[now]) return;
	dfs2(wson[now],rt);
	for(int i=0;i<t[now].size();i++){
		if(vis[t[now][i]]) continue;
		dfs2(t[now][i],t[now][i]);
	}return;
}
void update(int rt){
	sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
	return;
}
void build(int l,int r,int rt){
	if(l==r){
		sum[rt]=wei[l];
		sum[rt]%=mod;
		return;
	}
	int mid=(l+r)>>1;
	build(lson);build(rson);
	update(rt);
	return;
}
void color(int l,int r,int rt,int k){
	sum[rt]+=(r-l+1)*k;sum[rt]%=mod;
	tag[rt]+=k;tag[rt]%=mod;
	return;
}
void ph_tg(int l,int r,int rt){
	if(tag[rt]!=0){
		int mid=(l+r)>>1;
		color(lson,tag[rt]);
		color(rson,tag[rt]);
		tag[rt]=0;
	}
	return;
}
void modify(int l,int r,int rt,int k){
	//cout<<x<<' '<<y<<' '<<l<<' '<<r<<' '<<rt<<' '<<k<<endl;
	if(x<=l&&r<=y){
		color(l,r,rt,k);return;
	}
	ph_tg(l,r,rt);
	int mid=(l+r)>>1;
	if(x<=mid) modify(lson,k);
	if(y>mid) modify(rson,k);
	update(rt);
	return;
}
int query(int l,int r,int rt){
	if(x<=l&&r<=y){
		return sum[rt];
	}
	int mid=(l+r)>>1,ans=0;
	if(x<=l) ans=(ans+query(lson))%mod;
	if(y>r) ans=(ans+query(rson))%mod;
	return ans;
}
int query_path(int xx,int yy){
	int ans=0;
	while(top[xx]!=top[yy]){
		if(dep[top[xx]]<dep[top[yy]]) swap(xx,yy);
		x=id[top[xx]];y=yy;
		ans=(ans+query(1,n,1))%mod;
		xx=fa[top[xx]];
	}
	if(dep[xx]>dep[yy]) swap(xx,yy);
	x=id[xx];y=id[yy];
	ans=(ans+query(1,n,1))%mod;
	return ans;
}
int query_son(int xx){
	x=id[xx];y=id[xx]+siz[xx]-1;
	return query(1,n,1);
}
void modify_path(int xx,int yy,int k){
	k%=mod;
	while(top[xx]!=top[yy]){
		if(dep[top[xx]]<dep[top[y]]) swap(x,y);
		x=id[top[xx]];y=id[xx];
		modify(1,n,1,k);
		xx=fa[top[xx]];
	}
	if(dep[xx]>dep[yy]) swap(xx,yy);
	x=id[xx];y=id[yy];
	modify(1,n,1,k);
	return;
}
void modify_son(int xx,int k){
	x=id[xx];y=id[xx]+siz[xx]-1;
	//cout<<xx<<' '<<id[xx]<<' '<<siz[xx]<<endl;
	modify(1,n,1,k);
	return;
}
signed main(){
	cin>>n>>m>>rt>>p;mod=p;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1,u,v;i<n;i++){
		cin>>u>>v;
		t[u].push_back(v);
		t[v].push_back(u);
	}
	dfs1(rt,1,1);memset(vis,0,sizeof(vis));
	dfs2(rt,rt);//Here is a pot
	//cout<<endl;
	build(1,n,1);
	//for(int i=1;i<=n;i++){
	//	cout<<siz[i]<<' ';
	//}cout<<endl;
	for(int i=1;i<=n;i++){
		cout<<id[i]<<' ';
	}cout<<endl;
	for(int i=1;i<=n*2;i++){
		cout<<sum[i]<<' ';
	}cout<<endl;
	while(m--){//r--x e--y s--z
		cin>>op>>r;
		if(op==1){
			cin>>e>>s;
			modify_path(r,e,s);
		}else if(op==2){
			cin>>e;
			cout<<query_path(r,e)<<endl;
		}else if(op==3){
			cin>>s;
			modify_son(r,s);
		}else{
			cout<<query_son(r)<<endl;
		}
	}
	return 0;
}
2024/3/4 19:43
加载中...