The first root is root, and after the root change, for the current root rtnow and ask subtree u,
①rtnow==u, ask the whole tree.
②fa[rtnow]==u, asking the whole tree except for the Rtnow tree
③rtnow in the subtree of U, and the distance greater than 1, asking the whole tree except for the rtnow of the ancestor of the son whose ancestor is U.
④rtnow not in the subtree of U, ask the subtree of U
For ③, jumping on the tree chain is good, it can be violent, and complexity cannot be guaranteed.
#include <cstdio> #include <algorithm> #include <cmath>using namespace std; #define N 100001#define INF 2147483647#define Lson rt<<1,l,m#define Rson rt<<1|1,m+1,rint v[n<<1],en,next[n<<1],first[n ];void addedge (int u,int V) {v[++en]=v;next[en]=first[u];first[u]=en;} int n,m,root,a[n];int ls[n],rs[n],top[n],siz[n],fa[n],dep[n],tot,son[n],rtnow,map[n];void DFS (int U) {siz[U]=1;for ( int i=first[u];i;i=next[i]) if (V[i]!=fa[u]) {fa[v[i]]=u; dep[v[i]]=dep[u]+1; DFS (V[i]); Siz[u]+=siz[v[i]]; if (Siz[v[i]]>siz[son[u]]) son[u]=v[i]; }}void dfs2 (int U) {ls[u]=++tot; Map[tot]=u;if (Son[u]) {top[son[u]]=top[u]; DFS2 (Son[u]); }for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&v[i]!=son[u]) {top[v[i]]=v[i]; DFS2 (V[i]); }rs[u]=tot;} int minv[n<<2],cov[n<<2];void pushdown (int rt) {if (Cov[rt]) {cov[rt<<1]=cov[rt<<1|1]=minv[ rt<<1]=minv[rt<<1|1]=cov[rt]; cov[rt]=0; }}vOID Update (int ql,int qr,int v,int rt,int l,int R) {if (QL<=L&&R<=QR) {cov[rt]=minv[rt]=v; Return }pushdown (RT), int m= (l+r>>1), if (ql<=m) update (Ql,qr,v,lson), if (M<QR) update (Ql,qr,v,rson); minv[rt]= Min (minv[rt<<1],minv[rt<<1|1]);} int query (int ql,int qr,int rt,int l,int R) {if (QL<=L&&R<=QR) return MINV[RT];p Ushdown (RT); int m= (l+r>& gt;1), Res=inf;if (ql<=m) res=min (Res,query (Ql,qr,lson)), if (M<QR) res=min (Res,query (Ql,qr,rson)); return res;} void Update (int u,int v,int W) {int F1=top[u],f2=top[v],res=inf;while (F1!=F2) {if (Dep[f1]<dep[f2]) {Swap (f1,f2 ); Swap (U,V); } update (LS[F1],LS[U],W,1,1,N); U=fa[u]; F1=top[u]; }if (Dep[u]>dep[v]) swap (U,V); update (ls[u],ls[v],w,1,1,n);} int main () {//freopen ("bzoj3083.in", "R", stdin), int a,b,c,op;scanf ("%d%d", &n,&m), for (int i=1;i<n;++i) { scanf ("%d%d", &a,&b); Addedge (A, b); Addedge (B,a); }for (int i=1;i<=n;++i) scanf ("%d", &a[i]); scanf ("%d", &amP;root); Top[root]=root;dfs (Root);d fs2 (Root), for (int i=1;i<=n;++i) update (LS[I],LS[I],A[I],1,1,N), for (; m;--m) { scanf ("%d", &op); if (op==1) scanf ("%d", &rtnow); else if (op==2) {scanf ("%d%d%d", &a,&b,&c); Update (A,B,C); } else {scanf ("%d", &a); if (a==rtnow) printf ("%d\n", Query (1,n,1,1,n)); else if (fa[rtnow]==a) printf ("%d\n", min (Query (1,ls[rtnow]-1,1,1,n), rs[rtnow]==n?) Inf:query (Rs[rtnow]+1,n,1,1,n)); else if (Ls[rtnow]>=ls[a]&&ls[rtnow]<=rs[a]) {int u=rtnow; while (Fa[top[u]]!=a&&top[u]!=top[a]) u=fa[top[u]]; if (fa[top[u]]!=a) u=map[ls[a]+1]; else U=top[u]; printf ("%d\n", min (Query (1,ls[u]-1,1,1,n), rs[u]==n?) Inf:query (Rs[u]+1,n,1,1,n)); } else printf ("%d\n", Query (Ls[a],rs[a],1,1,n)); }}return 0;}
Tree chain subdivision, Segment tree, block tree, bzoj3083 remote country