遥远的国度(换根+树剖)

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<cstdio>
  5 #include<algorithm>
  6 using namespace std;
  7 const long long N=100010;
  8 long long cnt,head[N];
  9 long long size[N],fa[N],ff[N][30],son[N],dep[N];
 10 long long tot,top[N],w[N],id[N];
 11 long long a[N],root,n,m;
 12 struct edge{
 13     long long to,nxt;
 14 }e[N*3];
 15 struct tree{
 16     long long minn,l,r,lazy;
 17 }tr[N*8];
 18 void add(long long u,long long v){
 19     cnt++;
 20     e[cnt].nxt=head[u];
 21     e[cnt].to=v;
 22     head[u]=cnt;
 23 }
 24 void dfs1(long long u,long long f,long long deep){
 25     size[u]=1;
 26     fa[u]=f;
 27     ff[u][0]=f;
 28     dep[u]=deep;
 29     long long maxson=-1;
 30     for(long long i=head[u];i;i=e[i].nxt){
 31         long long v=e[i].to;
 32         if(v==f)continue;
 33         dfs1(v,u,deep+1);
 34         size[u]+=size[v];
 35         if(maxson<size[v]){
 36             maxson=size[v];
 37             son[u]=v;
 38         }
 39     }
 40 }
 41 void dfs2(long long u,long long tp){
 42     top[u]=tp;
 43     id[u]=++tot;
 44     w[tot]=a[u];
 45     if(!son[u])return;
 46     dfs2(son[u],tp);
 47     for(long long i=head[u];i;i=e[i].nxt){
 48         long long v=e[i].to;
 49         if(v==fa[u]||v==son[u])continue;
 50         dfs2(v,v);
 51     }
 52 }
 53 void update(long long now){
 54     tr[now].minn=min(tr[now*2].minn,tr[now*2+1].minn);
 55 }
 56 void pushdown(long long now){
 57     if(tr[now].lazy==0)return;
 58     tr[now*2].minn=tr[now].lazy;
 59     tr[now*2+1].minn=tr[now].lazy;
 60     tr[now*2].lazy=tr[now*2+1].lazy=tr[now].lazy;
 61     tr[now].lazy=0;
 62 }
 63 void build(long long l,long long r,long long now){
 64     tr[now].l=l;tr[now].r=r;
 65     if(l==r){
 66         tr[now].minn=w[l];
 67         return;
 68     }
 69     long long mid=(l+r)>>1;
 70     build(l,mid,now*2);
 71     build(mid+1,r,now*2+1);
 72     update(now);
 73 }
 74 void change(long long l,long long r,long long c,long long now){
 75     pushdown(now);
 76     if(tr[now].l==l&&tr[now].r==r){
 77         tr[now].minn=c;
 78         tr[now].lazy=c;
 79         return;
 80     }
 81     long long mid=(tr[now].l+tr[now].r)>>1;
 82     if(l>mid)change(l,r,c,now*2+1);
 83     else if(r<=mid)change(l,r,c,now*2);
 84     else {
 85         change(l,mid,c,now*2);
 86         change(mid+1,r,c,now*2+1);
 87     }
 88     update(now);
 89 }
 90 long long getmin(long long l,long long r,long long now){
 91     pushdown(now);
 92     if(tr[now].l==l&&tr[now].r==r){
 93         return tr[now].minn;
 94     }
 95     long long mid=(tr[now].l+tr[now].r)>>1;
 96     if(l>mid)return getmin(l,r,now*2+1);
 97     else if(r<=mid)return getmin(l,r,now*2);
 98     else {
 99         return min(getmin(l,mid,now*2),getmin(mid+1,r,now*2+1));
100     }
101 }
102 long long getlca(long long x,long long y){
103     while(top[x]!=top[y]){
104         if(dep[top[x]]<dep[top[y]])swap(x,y);
105         x=fa[top[x]];
106     }
107     if(dep[x]<dep[y])return x;
108     else return y;
109 }
110 void changel(long long x,long long y,long long c){
111     while(top[x]!=top[y]){
112         if(id[top[x]]<id[top[y]])swap(x,y);
113         change(id[top[x]],id[x],c,1);
114         x=fa[top[x]]; 
115     }
116     if(dep[x]>dep[y])swap(x,y);
117     change(id[x],id[y],c,1);
118 }
119 int work(int x,int z){
120     for(int i=20;i>=0;i--){
121         if(dep[ff[z][i]]>dep[x]){
122             z=ff[z][i];
123         }
124     }
125     return z;
126 }
127 int main(){
128     scanf("%lld%lld",&n,&m);
129     for(long long i=1;i<n;i++){
130         long long u;long long v;
131         scanf("%lld%lld",&u,&v);
132         add(u,v);add(v,u);
133     }
134     for(long long i=1;i<=n;i++){
135         scanf("%lld",&a[i]);
136     }
137     scanf("%lld",&root);
138     dfs1(root,0,1);
139     dfs2(root,0);
140     for(int i=1;i<=20;i++)
141         for(int j=1;j<=n;j++){
142             ff[j][i]=ff[ff[j][i-1]][i-1];
143         }
144     build(1,n,1);
145     for(long long i=1;i<=m;i++){
146         long long k;
147         scanf("%lld",&k);
148         if(k==1){
149             long long x;
150             scanf("%lld",&x);
151             root=x;
152         }
153         else if(k==2){
154             long long x,y,w;
155             scanf("%lld%lld%lld",&x,&y,&w);
156             changel(x,y,w);
157         }
158         else {
159             long long x;
160             scanf("%lld",&x);
161             long long LCA=getlca(root,x);
162             if(x==root){
163                 printf("%lld
",getmin(1,n,1));
164             }
165             else if(LCA!=x){
166                 printf("%lld
",getmin(id[x],id[x]+size[x]-1,1));
167             }
168             else{
169                 long long ans=4e18;
170              //   cout<<root<<" "<<id[root]<<" "<<id[root]+size[root]-1<<"bbbbbb"<<endl; 
171                 int y=work(x,root);
172              //   cout<<y<<endl;
173                 if(id[y]!=1)ans=min(ans,getmin(1,id[y]-1,1));
174                 if(id[y]+size[y]-1!=n)ans=min(ans,getmin(id[y]+size[y],n,1)); 
175                 printf("%lld
",ans);
176             }
177         }
178     }
179     return 0;
180 } 
原文地址:https://www.cnblogs.com/Xu-daxia/p/9451064.html