MnZn求助LCT维护子树信息模板
查看原帖
MnZn求助LCT维护子树信息模板
285617
黑影洞人楼主2022/11/15 15:42
#include<cstdio>
#include<algorithm>
#include<set>
#define N 114514
#define inf 2147483647
using namespace std;
int n,m;
int head[N],to[N],nxt[N],tot,rt;
void add(int u,int v){
	to[++tot]=v;
	nxt[tot]=head[u];
	head[u]=tot;
}
struct link_cut_tree{
	int ch[N][2],f[N],stk[N],val[N],ans[N],tag[N],mn[N],tr[N];
	bool r[N];
	multiset<int>st[N];
	#define lc ch[x][0]
	#define rc ch[x][1]
	void pushup(int x){
		mn[x]=ans[x]=x;tr[x]=inf;
		mn[x]=min(mn[x],min(mn[lc],mn[rc]));
		tr[x]=min(*st[x].begin(),min(tr[lc],tr[rc]));
		ans[x]=min(mn[x],tr[x]);
	}
	void rev(int x){swap(lc,rc),r[x]^=1;}
	int nroot(int x){return ch[f[x]][1]==x||ch[f[x]][0]==x;}
	int son(int x){return ch[f[x]][1]==x;}
	void rotate(int x){
		int y=f[x],z=f[y],k=son(x),w=ch[x][!k];
		if(nroot(y))ch[z][son(y)]=x;
		ch[x][!k]=y,ch[y][k]=w;
		if(!w)f[w]=y;
		f[x]=z,f[y]=x;
		pushup(y);
	}
	void assign(int x,int v){
		if(!x)return;
		mn[x]=val[x]=v;tag[x]=v;
		ans[x]=min(mn[x],tr[x]); 
	}
	void pushdown(int x){
		if(r[x]){
			if(lc)rev(lc);
			if(rc)rev(rc);
			r[x]=0; 
		}
		if(tag[x]){
			if(lc)assign(lc,tag[x]);
			if(rc)assign(rc,tag[x]);
			tag[x]=0;
		}
	}
	void splay(int x){
		int y=x,z=0;
		stk[++z]=y;
		while(nroot(y))stk[++z]=y=f[y];
		while(z)pushdown(stk[z--]);
		while(nroot(x)){
			y=f[x];
			if(nroot(y))rotate(son(x)!=son(y)?x:y);
			rotate(x);
		}
		pushup(x);
	}
	void access(int x){
		for(int y=0;x;x=f[y=x]){
			splay(x);
			if(y)st[x].erase(st[x].lower_bound(ans[y]));
			if(rc)st[x].insert(ans[rc]);
			rc=y;pushup(x);
		}
	}
	void makeroot(int x){access(x),splay(x),rev(x);}
	void split(int x,int y){makeroot(x),access(y),splay(y);}
}lct;
void dfs(int x,int fa){
	lct.st[x].insert(inf);
	lct.f[x]=fa;
	for(int i=head[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa)continue;
		dfs(y,x);
		lct.st[x].insert(lct.ans[y]);
	}
	lct.pushup(x);
}
signed main(){
	lct.st[0].insert(inf);
	lct.tr[0]=inf,lct.mn[0]=inf,lct.val[0]=inf;
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		add(a,b);add(b,a);
	}
	for(int i=1;i<=n;i++){
		int a;
		scanf("%d",&a);
		lct.ans[i]=a,lct.val[i]=a,lct.mn[i]=a;
		lct.tr[i]=inf;
	}
	scanf("%d",&rt);
	dfs(rt,0);
	lct.makeroot(rt);
	while(m--){
		int op,x,y,v;
		scanf("%d%d",&op,&x);
		if(op==1){
			rt=x;
			lct.makeroot(x);
		}else if(op==2){
			scanf("%d%d",&y,&v);
			lct.split(x,y);
			lct.assign(y,v);
			lct.makeroot(rt); 
		}else{
			lct.access(x),lct.splay(x);
			printf("%d\n",min(lct.val[x],*lct.st[x].begin()));
		}
	}
	return 0;
}



2022/11/15 15:42
加载中...