刚学换跟树剖的袜子悬关求调!
查看原帖
刚学换跟树剖的袜子悬关求调!
782808
Nazale_楼主2023/11/9 20:10
#include<bits/stdc++.h>
#define int long long
#define INF 1e18
#define ls (u<<1)
#define rs ((u<<1)|1)
using namespace std;
const int maxn=1e5+5;
int n,m;
int head[maxn],cnt;
struct edge{
	int u,v,nxt;
}e[maxn<<1];
void add(int u,int v){
	e[++cnt].nxt=head[u];
	e[cnt].v=v;
	e[cnt].u=u;
	head[u]=cnt;
}
int fa[maxn],dep[maxn],top[maxn],siz[maxn],wc[maxn];
int dfn[maxn],vistime,t[maxn],rdfn[maxn],anc[maxn][20];
void dfs1(int u,int f){
	fa[u]=f;
	dep[u]=dep[f]+1;
	siz[u]=1;
	anc[u][0]=f;
	for (int i=1;i<=20;i++){
		anc[u][i]=anc[anc[u][i-1]][i-1];
		if(!anc[u][i]) break;
	}
	for (int i=head[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==f) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[wc[u]]<siz[v]) wc[u]=v;
	}
}
void dfs2(int u,int T){
	top[u]=T;
	dfn[u]=++vistime;
	rdfn[vistime]=u;
	if(!wc[u]) return;
	dfs2(wc[u],T);
	for (int i=head[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa[u] || v==wc[u]) continue;
		dfs2(v,v);
	}
}
int getfa(int x,int k){
	for (int i=20;i;i--){
		if(k>=(1<<i)){
			k-=(1<<i),x=anc[x][i];
		}
	}
	return x;
}
struct tree{
	int l,r;
	int w=INF;
	int tag=0;
}a[maxn<<2];
void pushup(int u){
	a[u].w=min(a[ls].w,a[rs].w);
}
void build(int u,int l,int r){
	a[u].l=l,a[u].r=r;
	if(l==r){
		a[u].w=t[rdfn[l]];
		return;
	}
	int mid=l+r>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(u);
}
void maketag(int u,int k){
	a[u].w=k;
	a[u].tag=k;
}
void pushdown(int u){
	if(a[u].tag){
		maketag(ls,a[u].tag);
		maketag(rs,a[u].tag);
		a[u].tag=0;
	}
	return;
}
void update(int u,int l,int r,int k){
	if(a[u].l>=l && a[u].r<=r){
		maketag(u,k);
		return;
	}
	int mid=a[u].l+a[u].r>>1;
	pushdown(u);
	if(mid>=l) update(ls,l,r,k);
	if(mid<r) update(rs,l,r,k);
	pushup(u);
}
void upd(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	}
	update(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),k);
}
int query(int u,int l,int r){
	if(a[u].l>=l && a[u].r<=r){
		return a[u].w;
	}
	int mid=a[u].l+a[u].r>>1;
	pushdown(u);
	int ans=INF;
	if(mid>=l) ans=min(ans,query(ls,l,r));
	if(mid<r) ans=min(ans,query(rs,l,r));
	return ans;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for (int u,v,i=1;i<n;i++){
		cin>>u>>v;
		add(u,v);
		add(v,u);	
	}
	for (int i=1;i<=n;i++){
		cin>>t[i];
	}
	int root;
	cin>>root;
	dfs1(1,0);
	dfs2(1,0);
	build(1,1,n);
	while(m--){
		int op,id,x,y,v;
		cin>>op;
		if(op==1){
			cin>>id;
			root=id;
		}
		else if(op==2){
			cin>>x>>y>>v;
			upd(x,y,v);
		}
		else{
			cin>>id;
			if(id==root){
				cout<<a[1].w<<"\n";
				continue;
			}
			if(dep[id]<dep[root]&&anc[y=getfa(root,dep[root]-dep[id]-1)][0]==x){
				int p,q=INF;
				p=query(1,dfn[1],dfn[y]-1);
				if(dfn[y]+siz[y]<=n) q=query(1,dfn[y]+siz[y],n);
				cout<<min(p,q)<<"\n";
			}
			else{
				cout<<query(1,dfn[id],dfn[id]+siz[id]-1)<<"\n";
			}
			
		}
	}
	
	return 0;
}

学习的第一个题解的大佬的方法,求帮助!!

2023/11/9 20:10
加载中...