……喵的WA了兩把,第一把是……倍增查詢是否爲lca的時候……忘記賦值anc[i][0] = father[i]了………………
第二把……………………我……INF開小了…………GGGGGGG
#include<bits/stdc++.h>
#define MAXN 100005
#define INF INT_MAX
using namespace std; int n,m;
inline int read(){
char ch = getchar();
while((ch^'-')&&!isdigit(ch)) ch = getchar();
int rtn = 0 , f = 1;
if(ch=='-') f = -1 , ch = getchar();
while(isdigit(ch)) rtn = rtn*10 + ch - '0' , ch = getchar();
return f*rtn;
}
int root;
struct t1{
int to,nxt;
}edge[MAXN<<1]; int cnt_edge = 0;
int fst[MAXN];
void addedge(int x,int y){
edge[++cnt_edge].to = y;
edge[cnt_edge].nxt = fst[x];
fst[x] = cnt_edge;
edge[++cnt_edge].to = x;
edge[cnt_edge].nxt = fst[y];
fst[y] = cnt_edge;
}
int fth[MAXN] , siz[MAXN] , son[MAXN] , top[MAXN];
int dpt[MAXN] , anc[MAXN][18];
int val[MAXN];
void dfs1(int now){
siz[now] = 1;
for(int i=1;i<18;++i) anc[now][i] = anc[ anc[now][i-1] ][i-1];
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(aim==fth[now]) continue;
fth[aim] = anc[aim][0] = now;
dpt[aim] = dpt[now]+1;
dfs1(aim);
siz[now] += siz[aim];
if(siz[aim] > siz[son[now]]) son[now] = aim;
}
}
int dfn[MAXN] , idf[MAXN] , cnt_dfs = 0;
void dfs2(int now,int tp){
top[now] = tp;
dfn[now] = ++cnt_dfs;
idf[cnt_dfs] = now;
if(son[now]) dfs2(son[now],tp);
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(aim==fth[now]||aim==son[now]) continue;
dfs2(aim,aim);
}
}
int dt[MAXN<<2] , tag[MAXN<<2];
void build(int now,int l,int r){
tag[now] = -1;
if(l==r) return void(dt[now] = val[idf[l]]);
int mid = (l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
dt[now] = min(dt[now<<1] , dt[now<<1|1]);
}
inline void pushdown(int now){
dt[now<<1] = tag[now<<1] = tag[now];
dt[now<<1|1] = tag[now<<1|1] = tag[now];
tag[now] = -1;
}
int inqry(int now,int l,int r,int L,int R){
if(L<=l&&r<=R) return dt[now];
if(~tag[now]) pushdown(now);
int mid = (l+r)>>1;
int tmp = INF;
if(L<=mid) tmp = inqry(now<<1,l,mid,L,R);
if(mid<R) tmp = min(tmp , inqry(now<<1|1,mid+1,r,L,R));
return tmp;
}
void modify(int now,int l,int r,int L,int R,int v){
if(L<=l&&r<=R) return void(dt[now] = tag[now] = v);
if(~tag[now]) pushdown(now);
int mid = (l+r)>>1;
if(L<=mid) modify(now<<1,l,mid,L,R,v);
if(mid<R) modify(now<<1|1,mid+1,r,L,R,v);
dt[now] = min(dt[now<<1] , dt[now<<1|1]);
}
inline void work_modify_chain(int u,int v,int k){
while(top[u]^top[v]){
if(dpt[top[u]] > dpt[top[v]]){
modify(1,1,n,dfn[top[u]] , dfn[u],k);
u = fth[top[u]];
}
else{
modify(1,1,n,dfn[top[v]] , dfn[v],k);
v = fth[top[v]];
}
}
if(dpt[u]<dpt[v])
modify(1,1,n,dfn[u],dfn[v],k);
else modify(1,1,n,dfn[v],dfn[u],k);
}
int AIM;
inline bool is_ANC(int u,int v){
if(dpt[u]>=dpt[v]) return 0;
for(int dlt = dpt[v] - dpt[u] - 1 , i = 0;i<18;++i)
if(dlt&(1<<i))
v = anc[v][i];
if(u==fth[v]) return AIM = v,1;
return 0;
}
int cnttt = 0;
inline void work_ask_subtree(int x){
++cnttt;
if(x==root){
printf("%d\n",dt[1]);
return ;
}
if(is_ANC(x,root)){
int ans = INF;
if(dfn[AIM]>1) ans = inqry(1,1,n,1,dfn[AIM] - 1);
if(dfn[AIM]<n) ans = min(ans,inqry(1,1,n,dfn[AIM]+siz[AIM],n));
printf("%d\n",ans);
}
else
printf("%d\n",inqry(1,1,n,dfn[x],dfn[x]+siz[x]-1));
}
int opt;
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
n = read() , m = read();
for(int i=1;i<n;++i)
addedge(read(),read());
for(int i=1;i<=n;++i) val[i] = read();
root = read();
dpt[root] = 1;
dfs1(root);
dfs2(root,root);
build(1,1,n);
while(m--){
opt = read();
if(opt==1)
root = read();
else{
if(opt==2){
int x,y,z;
x = read() , y = read() , z = read();
work_modify_chain(x,y,z);
}
else
work_ask_subtree(read());
}
}
return 0;
}