只能过第一个点。码风优良,求调十分感谢。
#include <bits/stdc++.h>
using namespace std;
#define ls u<<1
#define rs u<<1|1
const int N = 1e5 + 5;
int n, m;
int rt;
vector<int>e[N];
int w[N];
int id[N], nw[N], cnt;
int fa[N], son[N], siz[N], top[N], dep[N];
void dfs1(int u, int f)
{
siz[u] = 1;
dep[u] = dep[f] + 1;
fa[u] = f;
for (int v : e[u]) {
if (v == f) continue;
dfs1(v, u);
siz[u] += siz[v];
if (siz[son[u]] < siz[v]) son[u] = v;
}
}
void dfs2(int u, int t)
{
top[u] = t; id[u] = ++cnt; nw[cnt] = w[u];
if (!son[u]) return;
dfs2(son[u], t);
for (int v : e[u]) {
if (v == son[u] || v == fa[u]) continue;
dfs2(v, v);
}
}
struct Segm{
int l, r, minv, tag;
Segm() {minv = 1e9; tag = 0;}
} tree[N << 2];
inline void pushup(int u) {tree[u].minv = min(tree[ls].minv, tree[rs].minv); }
inline void pushdown(int u)
{
if (tree[u].tag) {
tree[ls].minv = tree[rs].minv = tree[u].tag;
tree[ls].tag = tree[rs].tag = tree[u].tag;
tree[u].tag = 0;
}
}
void build(int u, int l, int r)
{
tree[u].l = l, tree[u].r = r;
if (l == r) {
tree[u].minv = nw[l]; // mention
return ;
}
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(u);
}
void qqq(int u, int l, int r)
{
if (l == r) {
cout << tree[u].minv << " ";
return ;
}
int mid = l + r >> 1;
qqq(ls, l, mid);
qqq(rs, mid + 1, r);
}
void modify(int u, int l, int r, int val)
{
if (l <= tree[u].l && tree[u].r <= r) {
tree[u].minv = val;
tree[u].tag = val;
return;
}
pushdown(u);
int mid = tree[u].l + tree[u].r >> 1;
if (mid >= l) modify(ls, l, r, val);
if (mid < r) modify(rs, l, r, val);
pushup(u);
}
int query(int u, int l, int r)
{
if (l <= tree[u].l && tree[u].r <= r) {
return tree[u].minv;
}
pushdown(u);
int ans = 1e9;
int mid = tree[u].l + tree[u].r >> 1;
if (mid >= l) ans = min(ans, query(ls, l, r));
if (mid < r) ans = min(ans, query(rs, l, r));
return ans;
}
int lca(int u, int v)
{
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
void modify_sect(int u, int v, int val)
{
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
modify(1, id[top[u]], id[u], val);
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
modify(1, id[v], id[u], val);
}
int query_subtree(int u)
{
if (u == rt) {
return tree[1].minv; // mention
} else if (dep[u] < dep[rt] && lca(u, rt) == u) {
return min(query(1, 1, id[rt] - 1), query(1, id[rt] + siz[rt], n)); // wrong
} else {
return query(1, id[u], id[u] + siz[u] - 1);
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i < n; i++) {
scanf("%d%d", &u, &v);
e[u].push_back(v);
e[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &w[i]);
}
scanf("%d", &rt);
dfs1(rt, 0);
dfs2(rt, rt);
build(1, 1, n);
// cout << query(1, 1, 1) << " " << query(1, 2, 2) << " " << query(1, 3, 3) << endl;
for (int i = 1, op, u, v, w; i <= m; i++) {
scanf("%d", &op);
if (op == 1) {
scanf("%d", &rt);
} else if (op == 2) {
scanf("%d%d%d", &u, &v, &w);
modify_sect(u, v, w);
} else {
scanf("%d", &u);
printf("%d\n", query_subtree(u));
}
}
return 0;
}