RT,一上午了,思路就是主流思路。
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define next nxt
#define re register
#define il inline
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const int INF = 1e18;
using namespace std;
int max(int x,int y){return x > y ? x : y;}
int min(int x,int y){return x < y ? x : y;}
struct node{
int u,v,next;
}edge[M<<1]; int head[N],num_edge;
int w[N],wt[N];
int n,m,u,v,x,y,k,op,root;
int tree[N<<2],tag[N<<2];
int son[N],id[N],fa[N][23],tot,dep[N],siz[N],top[N];
il int read()
{
int f=0,s=0;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
return f ? -s : s;
}
il void add(int from,int to)
{
edge[++num_edge] = (node){from,to,head[from]};
head[from] = num_edge;
}
#define lc p<<1
#define rc p<<1|1
il void build(int p,int l,int r)
{
if(l == r)
{
tree[p] = wt[l];
return ;
}
int mid = (l+r) >> 1;
build(lc,l,mid);
build(rc,mid+1,r);
tree[p] = min(tree[lc],tree[rc]);
}
il void push_down(int p)
{
tag[lc] = tag[rc] = tag[p];
tree[lc] = tree[rc] = tag[p];
tag[p] = 0;
}
il void Modify(int nl,int nr,int l,int r,int p,int k)
{
if(l >= nl && r <= nr)
{
tag[p] = tree[p] = k;
return ;
}
if(tag[p]) push_down(p);
int mid = (l+r) >> 1;
if(nl <= mid) Modify(nl,nr,l,mid,lc,k);
if(nr > mid) Modify(nl,nr,mid+1,r,rc,k);
tree[p] = min(tree[lc],tree[rc]);
}
il int Query(int nl,int nr,int l,int r,int p)
{
int res = INF;
if(l >= nl && r <= nr) return tree[p];
if(tag[p]) push_down(p);
int mid = (l+r) >> 1;
if(nl <= mid) res = min(res,Query(nl,nr,l,mid,lc));
if(nr > mid) res = min(res,Query(nl,nr,mid+1,r,rc));
return res;
}
/*------------------------------------------*/
il void dfs1(int x,int f)
{
dep[x] = dep[f] + 1 , fa[x][0] = f , siz[x] = 1;
for(re int i=head[x];i;i=edge[i].next)
{
int y = edge[i].v;
if(y == f) continue;
dfs1(y,x);
siz[x] += siz[y];
if(siz[son[x]] < siz[y]) son[x] = y;
}
}
il void dfs2(int x,int topf)
{
id[x] = ++tot , wt[tot] = w[x] , top[x] = topf;
if(!son[x]) return ;
dfs2(son[x],topf);
for(re int i=head[x];i;i=edge[i].next)
{
int y = edge[i].v;
if(y == fa[x][0] || y == son[x]) continue;
dfs2(y,y);
}
}
il void init()
{
for(re int j=1;j<=22;j++)
for(re int i=1;i<=n;i++)
fa[i][j] = fa[fa[i][j-1]][j-1];
}
il int LCA(int x,int y)
{
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x,y);
x = fa[top[x]][0];
}
return dep[x] < dep[y] ? x : y;
}
il void Modify_way(int x,int y,int k)
{
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x,y);
Modify(id[top[x]],id[x],1,n,1,k);
x = fa[top[x]][0];
}
if(dep[x] > dep[y]) swap(x,y);
Modify(id[x],id[y],1,n,1,k);
}
il int jump(int x,int depth)
{
for(re int i=22;i>=0;i--) if(dep[fa[x][i]] >= depth) x = fa[x][i];
return x;
}
il void Query_way(int x)
{
if(x == root) { cout << tree[1] << "\n"; return ; }
int lca = LCA(x,root);
if(lca == x)
{
int y = jump(root,dep[root]-dep[x]-1);
int p=INF,q=INF;
if(id[y]-1 >= 1) p = Query(1,id[y]-1,1,n,1);
if(id[y]+siz[y] <= n) q = Query(id[y]+siz[y],n,1,n,1);
cout << min(p,q) << "\n";
}
else cout << Query(id[x],id[x]+siz[x]-1,1,n,1) << "\n";
}
signed main()
{
n = read() , m = read();
for(re int i=1;i<=n-1;i++)
{
u = read() , v = read();
add(u,v) , add(v,u);
}
for(re int i=1;i<=n;i++) w[i] = read();
root = read();
dfs1(1,0);
dfs2(1,1);
init();
build(1,1,n);
for(re int i=1;i<=m;i++)
{
op = read();
if(op == 1) root = read();
if(op == 2) x=read(),y=read(),k=read(),Modify_way(x,y,k);
if(op == 3) x=read() , Query_way(x);
}
return 0;
}