除 #4 WA之外,全部 RE
#include<bits/stdc++.h>
#define L fa << 1
#define R fa << 1 | 1
#define mid (l + r >> 1)
using namespace std;
const int N = 1e6 + 4;
int n,m,cap,ncap;
int val[N],lg[N];
vector<int> t[N],l[N];
int hson[N],siz[N],d[N],fa[N];
void dfs1(int x,int pre) {
siz[x] = 1, hson[x] = 0;
for(int v : t[x]) {
if(v == pre) continue;
d[v] = d[x] + 1; fa[v] = x;
dfs1(v,x);
siz[x] += siz[v];
if(siz[v] > siz[hson[x]]) hson[x] = v;
}
}
int id,top[N],dfn[N],rk[N];
void dfs2(int x,int tp) {
id ++, dfn[id] = x, rk[x] = id, top[x] = tp;
if(hson[x]) dfs2(hson[x],tp);
for(int v : t[x]) {
if(v == fa[x]) continue;
l[x].push_back(dfn[v]);
if(v == hson[x]) continue;
dfs2(v,v);
}
}
int mn[N << 2],tg[N << 2];
inline int merge(int a,int b) { return min(a,b); }
inline void build(int fa,int l,int r) {
tg[fa] = -1;
if(l == r) {
mn[fa] = val[rk[l]];
return;
}
build(L,l,mid), build(R,mid+1,r);
mn[fa] = merge(mn[L],mn[R]);
}
inline void pd(int fa) {
if(tg[fa] == -1) return;
mn[L] = tg[L] = tg[fa], mn[R] = tg[R] = tg[fa];
tg[fa] = -1;
return ;
}
void update(int fa,int l,int r,int ql,int qr,int dt) {
if(ql <= l && r <= qr) {
mn[fa] = tg[fa] = dt;
return ;
}
pd(fa);
if(ql <= mid) update(L,l,mid,ql,qr,dt);
if(qr > mid) update(R,mid+1,r,ql,qr,dt);
mn[fa] = merge(mn[L],mn[R]);
}
int query(int fa,int l,int r,int ql,int qr) {
if(ql <= l && r <= qr) return mn[fa];
pd(fa);
int res = 2e9;
if(ql <= mid) res = min(res,query(L,l,mid,ql,qr));
if(qr > mid) res = min(res,query(R,mid+1,r,ql,qr));
return res;
}
void q_up(int u,int v,int k) {
while(top[u] != top[v]) {
if(d[top[u]] < d[top[v]]) swap(u,v);
update(1,1,n,dfn[top[u]],dfn[u],k);
u = fa[top[u]];
}
if(d[u] > d[v]) swap(u,v);
update(1,1,n,dfn[u],dfn[v],k);
return ;
}
int q_lca(int u,int v) {
while(top[u] != top[v]) {
if(d[top[u]] < d[top[v]]) swap(u,v);
u = fa[top[u]];
}
return top[u];
}
int q_sub(int u) { return query(1,1,n,dfn[u],dfn[u]+siz[u]-1); }
int q_seg(int u,int v) {
int res = 2e9;
while(top[u] != top[v]) {
if(d[top[u]] < d[top[v]]) swap(u,v);
res = min(res,query(1,1,n,dfn[top[u]],dfn[u]));
u = fa[top[u]];
}
if(d[u] > d[v]) swap(u,v);
res = min(res,query(1,1,n,dfn[u],dfn[v]));
return res;
}
void check(int fa,int l,int r) {
printf("l:%d r:%d val:%d\n",l,r,mn[fa]);
if(l == r) return;
check(L,l,mid);
check(R,mid+1,r);
}
int main() {
scanf("%d %d",&n,&m);
for(int i = 1; i < n; i ++) {
int u,v;
scanf("%d %d",&u,&v);
t[u].push_back(v), t[v].push_back(u);
}
for(int i = 1; i <= n; i ++) scanf("%d",&val[i]);
scanf("%d",&cap);
fa[cap] = 0;
dfs1(cap,0),dfs2(cap,cap);
build(1,1,n);
ncap = cap;
for(int i = 1; i <= m; i ++) {
int opt;
scanf("%d",&opt);
// printf("check:");
// check(1,1,n);
if(opt == 1) scanf("%d",&ncap);
else if(opt == 2) {
int x,y,v; scanf("%d %d %d",&x,&y,&v);
q_up(x,y,v);
}
else {
int u; scanf("%d",&u);
int lca = q_lca(u,ncap);
// printf("lca:%d\n",lca);
if(lca == ncap) printf("%d\n",q_sub(u));
else if(u == ncap) printf("%d\n",query(1,1,n,1,n));
else {
// cout << "type2" << endl;
int chd = *lower_bound(l[u].begin(),l[u].end(),dfn[ncap]);
int p = q_seg(rk[1],rk[dfn[chd] - 1]), q = q_seg(rk[dfn[ncap] + siz[ncap]],rk[n]);
printf("%d\n",min(p,q));
}
}
}
return 0;
}
/*
3 7
1 2
1 3
1 2 3
1
3 1
2 1 1 6
3 1
2 2 2 5
3 1
2 3 3 4
3 1
*/