If there is no root replacement operation, it can be maintained directly by tree dissection. Considering that the modification operation is root-independent, only special query operations are needed.
For query operations, assuming that the query point is x, the initial root is 1, and the actual root is r, there are three situations to consider: 1. If lca(r,x)!=x or x=r, the sub-tree with X as the root can be queried directly;
2. If lca(r,x)=x and x!=r, the whole tree is queried except for the sub-tree rooted by son (son is the son of X and the ancestor of r).
PS: If we don't use doubling and use tree dissection to find lca, then the search for son is a little complicated, which needs to be discussed in classification: 1. When the final two points after tree dissection x and r are the same, the top of the last tree dissection is son; 2. When the two points are different, it is the key son of x.
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define N 100005 5 #define mid (l+r>>1) 6 #define L (k<<1) 7 #define R (L+1) 8 struct ji{ 9 int nex,to; 10 }edge[N<<1]; 11 int E,n,m,x,y,r,p,head[N],fa[N],id[N],top[N],sz[N],ma[N],sh[N]; 12 ll z,f[N<<2],laz[N<<2]; 13 void add(int x,int y){ 14 edge[E].nex=head[x]; 15 edge[E].to=y; 16 head[x]=E++; 17 } 18 void dfs(int k,int f,int s){ 19 fa[k]=f; 20 sh[k]=s; 21 sz[k]=1; 22 for(int i=head[k];i!=-1;i=edge[i].nex) 23 if (edge[i].to!=f){ 24 dfs(edge[i].to,k,s+1); 25 sz[k]+=sz[edge[i].to]; 26 if (sz[edge[i].to]>sz[ma[k]])ma[k]=edge[i].to; 27 } 28 } 29 void dfs2(int k,int t){ 30 id[k]=++x; 31 top[k]=t; 32 if (ma[k])dfs2(ma[k],t); 33 for(int i=head[k];i!=-1;i=edge[i].nex) 34 if ((edge[i].to!=fa[k])&&(edge[i].to!=ma[k]))dfs2(edge[i].to,edge[i].to); 35 } 36 void down(int k){ 37 if (laz[k]){ 38 laz[L]=f[L]=laz[R]=f[R]=laz[k]; 39 laz[k]=0; 40 } 41 } 42 void update(int k,int l,int r,int x,int y,int z){ 43 if ((l>y)||(x>r))return; 44 if ((x<=l)&&(r<=y)){ 45 f[k]=laz[k]=z; 46 return; 47 } 48 down(k); 49 update(L,l,mid,x,y,z); 50 update(R,mid+1,r,x,y,z); 51 f[k]=min(f[L],f[R]); 52 } 53 ll query(int k,int l,int r,int x,int y){ 54 if ((l>y)||(x>r))return 3LL*0x3f3f3f3f; 55 if ((x<=l)&&(r<=y))return f[k]; 56 down(k); 57 return min(query(L,l,mid,x,y),query(R,mid+1,r,x,y)); 58 } 59 void update(int x,int y,int z){ 60 while (top[x]!=top[y]){ 61 if (sh[top[x]]<sh[top[y]])swap(x,y); 62 update(1,1,n,id[top[x]],id[x],z); 63 x=fa[top[x]]; 64 } 65 if (sh[x]>sh[y])swap(x,y); 66 update(1,1,n,id[x],id[y],z); 67 } 68 ll query(int x){ 69 if (x==r)return f[1]; 70 y=r; 71 int p=x; 72 while (top[x]!=top[y]){ 73 if (sh[top[x]]<sh[top[y]])swap(x,y); 74 z=top[x]; 75 x=fa[top[x]]; 76 } 77 if (sh[x]>sh[y])swap(x,y); 78 if (x!=p)return query(1,1,n,id[p],id[p]+sz[p]-1); 79 if (x!=y)z=ma[x]; 80 return min(query(1,1,n,1,id[z]-1),query(1,1,n,id[z]+sz[z],n)); 81 } 82 int main(){ 83 scanf("%d%d",&n,&m); 84 memset(head,-1,sizeof(head)); 85 for(int i=1;i<n;i++){ 86 scanf("%d%d",&x,&y); 87 add(x,y); 88 add(y,x); 89 } 90 dfs(1,0,0); 91 x=0; 92 dfs2(1,1); 93 for(int i=1;i<=n;i++){ 94 scanf("%lld",&z); 95 update(1,1,n,id[i],id[i],z); 96 } 97 scanf("%d",&r); 98 for(int i=1;i<=m;i++){ 99 scanf("%d%d",&p,&x); 100 if (p==1)r=x; 101 if (p==3)printf("%lld\n",query(x)); 102 if (p==2){ 103 scanf("%d%lld",&y,&z); 104 update(x,y,z); 105 } 106 } 107 }