30pts, 请求大佬调代码
查看原帖
30pts, 请求大佬调代码
544458
WAI_kycm楼主2023/8/15 20:44
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e7 + 5;
int n, m, a[maxn];
struct Node{
	int to, next;
}e[maxn];
int len, head[maxn];
void Insert(int u, int v){
	e[++len].to = v; e[len].next = head[u]; head[u] = len;
}
int cnt, dfn[maxn], rk[maxn], deep[maxn], siz[maxn], son[maxn], top[maxn], f[maxn];
void dfs1(int u){
	siz[u] = 1; deep[u] = deep[f[u]] + 1;
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v == f[u]) continue;
		f[v] = u;
		dfs1(v);
		siz[u] += siz[v];
		if(!son[u] or siz[son[u]] < siz[v]) son[u] = v;
	}
}
void dfs2(int u, int fa){
	top[u] = fa;
	dfn[u] = ++cnt;
	rk[cnt] = u;
	if( son[u]) dfs2(son[u], fa);
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v != f[u] and v != son[u]) dfs2(v, v);
	}
}

//以上为剖分

int tr[maxn], lazy[maxn];
void pushup(int rt) {tr[rt] = min(tr[rt << 1], tr[rt << 1 | 1]);}
void pushdown(int rt){
	if( lazy[rt]){
		lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
		tr[rt << 1] = tr[rt << 1 | 1] = lazy[rt];
		lazy[rt] = 0;
	}
}
void Build(int rt, int l, int r){
	if(l == r){
		tr[rt] = a[rk[l]];
		return;
	}
	int mid = l + r >> 1;
	Build(rt << 1, l, mid); Build(rt << 1 | 1, mid + 1, r);
	pushup(rt);
}
void update(int rt, int l, int r, int L, int R, int val){
	if(L <= l and r <= R){
		lazy[rt] = val;
		tr[rt] = val;
		return;
	}
	int mid = l + r >> 1;
	pushdown(rt);
	if(L <= mid) update(rt << 1, l, mid, L, R, val);
	if(R > mid) update(rt << 1 | 1, mid + 1, r, L, R, val);
	pushup(rt);
}
int query(int rt, int l, int r, int L, int R){
	if(L <= l and r <= R) return tr[rt];
	int mid = l + r >> 1, minn = 1e9;
	pushdown(rt);
	if(L <= mid) minn = min(minn, query(rt << 1, l, mid, L, R));
	if(R > mid) minn = min(minn, query(rt << 1 | 1, mid + 1, r, L, R));
	return minn;
}

//以上为线段树

void updatetree(int u, int v, int val){
	while(top[u] != top[v]){
		if(deep[top[u]] < deep[top[v]]) u ^= v ^= u ^= v;
		update(1, 1, n, dfn[top[u]], dfn[u], val);
		u = f[top[u]];
	}
	if(deep[u] > deep[v]) u ^= v ^= u ^= v;
	update(1, 1, n, dfn[u], dfn[v], val);
}

//小修改

int root;
int Find(int x, int rt){
	while(top[x] != top[rt]){
		if(f[top[rt]] == x) return top[rt];
		rt = f[top[rt]];
	}
	return son[x];
}

//找直系儿子

void Solve(){
	cin>>n>>m;
	for(int i = 1; i < n; ++i){
		int u, v; cin>>u>>v;
		Insert(u, v); Insert(v, u);
	}
	for(int i = 1; i <= n; ++i) cin>>a[i];
	cin>>root;
	dfs1(1); dfs2(1, 1); Build(1, 1, n);
	while(m--){
		int op; cin>>op;
		if(op == 1)	cin>>root;
		if(op == 2){
			int u, v, val; cin>>u>>v>>val;
			updatetree(u, v, val);
		}
        
    //因该是这下面错了吧,调了很久都不对    
    
		if(op == 3){
			int x; cin>>x;
			if(x == root) cout<<tr[1]<<endl;
			else if(dfn[root] <= dfn[x] or dfn[root] > dfn[x] + siz[x] - 1)	cout<<query(1, 1, n, dfn[x], dfn[x] + siz[x] - 1)<<endl;
			else{
				int y = Find(x, root);
				int ans = query(1, 1, n, 1, dfn[y] - 1);
				if(dfn[y] + siz[y] - 1 != n) ans = min(ans, query(1, 1, n, dfn[y] + siz[y], n));
				cout<<ans<<endl;
			}
		}
	}
}
signed main(){
	Solve();
	return 0;
}
2023/8/15 20:44
加载中...