20pts求调,悬二关
查看原帖
20pts求调,悬二关
373530
Reply_楼主2025/7/29 13:04
#include<bits/stdc++.h>
#define int long long
#define R1 register
#define F(i,a,b) for(int i = (a);i<=(b);i++)
using namespace std;
inline int read(){R1 int x=0,t=1;R1 char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*t;}
const int N=2e6+10;
int n,m,rt;
vector<int>g[N];
void add(int ui,int vi)
{
	g[ui].push_back(vi);
	return;
}
int siz[N],dep[N],fa[N],son[N];
void dfs1(int u,int Fa)
{
	siz[u]=1;
	dep[u]=dep[Fa]+1;
	fa[u]=Fa;
	for(int v:g[u]){
		if(v==Fa) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]]) son[u]=v;
	}
	return;
}
int id[N],top[N],b[N],val[N],tot;
void dfs2(int u,int topf)
{
	id[u]=++tot;
	top[u]=topf;
	b[tot]=val[u];
	if(son[u]) dfs2(son[u],topf);
	for(int v:g[u]){
		if(id[v]) continue;
		dfs2(v,v);
	}
}
#define ls(x) x*2
#define rs(x) x*2+1
struct node
{
	int l,r,minn,lazy;
}tr[N*4];
void pushup(int x)
{
	tr[x].minn=min(tr[ls(x)].minn,tr[rs(x)].minn);
	return;
}
void build(int x,int l,int r)
{
	tr[x].l=l,tr[x].r=r;
	tr[x].lazy=-1;
	if(l==r){
		tr[x].minn=b[l];
		return;
	}
	int mid=l+r>>1;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	pushup(x);
	return;
}
void pushdown(int x)
{
	if(tr[x].lazy!=-1){
		tr[ls(x)].minn=tr[ls(x)].lazy=tr[x].lazy;
		tr[rs(x)].minn=tr[rs(x)].lazy=tr[x].lazy;
		tr[x].lazy=-1;
	}
	return;
}
void update(int x,int l,int r,int k)
{
//	cout <<tr[x].l << " " << tr[x].r << " " <<  l << " " << r << '\n';
	if(tr[x].l>=l && tr[x].r<=r){
		tr[x].minn=k;
		tr[x].lazy=k;
		return;
	}
	pushdown(x);
	int mid=tr[x].l+tr[x].r>>1;
	if(mid>=l) update(ls(x),l,r,k);
	if(mid<r) update(rs(x),l,r,k);
	pushup(x);
}
void upRange(int x,int y,int k)
{
	while(top[x]!=top[y]){
	//	cout << x << " " << y << '\n';
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
//		cout << id[top[x]] << " " << id[x] << '\n';
		update(1,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
//	cout << id[x] << " " << id[y] << '\n';
	update(1,id[x],id[y],k);
	return;
}
int query(int x,int l,int r)
{
//	cout << l << " " << r << '\n';
	if(r<l) return 1e16;
	if(tr[x].l>=l && tr[x].r<=r){
		return tr[x].minn;
	}
	pushdown(x);
	int mid=tr[x].l+tr[x].r>>1,minn=1e16;
	if(mid>=l) minn=min(minn,query(ls(x),l,r));
	if(mid<r) minn=min(minn,query(rs(x),l,r));
	pushup(x);
	return minn;
}
int qson(int x)
{
	if(rt==x){
		return query(1,1,n);
	}
	if(id[rt]>=id[x] && id[rt]<=id[x]+siz[x]-1){
		//新根在x原子树内
		//1->id[rt]-1       id[rt]+siz[rt] -> n
//		assert(0);
		return min(query(1,1,id[rt]-1),query(1,id[rt]+siz[rt],n));
	}
	else{
		return query(1,id[x],id[x]+siz[x]-1);
	}
}
signed main()
{
	n=read(),m=read();
	for(int i = 2;i<=n;i++){
		int ui=read(),vi=read();
		add(ui,vi);
		add(vi,ui);
	}
	for(int i = 1;i<=n;i++){
		val[i]=read();
	}
	rt=read();
	dfs1(rt,0);
	dfs2(rt,rt);
//	for(int i = 1;i<=n;i++){
//		cout << i << " " << id[i] << '\n';
//	} 
	build(1,1,n);
//	cout << 11111 << '\n';
	for(int i = 1;i<=m;i++){
		int op=read();
		if(op==1){
			rt=read();
//			assert(0);
		}
		else if(op==2){
			int x=read(),y=read(),v=read();
			upRange(x,y,v);
		}
		else{
			int x=read();
			cout << qson(x) << '\n';
		}
	}
	return 0;
}
/*

*/


2025/7/29 13:04
加载中...