如果没有换根操作,可以直接用树剖维护,考虑修改操作与根无关,所以只需要特殊处理查询操作。
对于查询操作,假设查询点为x,初始的根是1,实际的根是r,一共要分三种情况来考虑:1. 若lca(r,x)!=x或x=r,则直接对以x为根的子树查询即可;
2. 若lca(r,x)=x且x!=r,则对整棵树除了以son为根的子树查询(son是x的边儿子也是r的祖先)。
PS:如果不使用倍增,使用树剖找lca,那么关于son的寻找有一点复杂,需要分类讨论:1.当树剖x和r之后最终的两点相同,则记录最后一次树剖的top即为son;2.当两点不同,就是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 }