[bzoj3083] A Far Country

Posted by VapiD on Wed, 31 Jul 2019 09:54:21 +0200

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 }

Topics: Python