遥远的国度(换根+树剖)
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\n",getmin(1,n,1)); 164 } 165 else if(LCA!=x){ 166 printf("%lld\n",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\n",ans); 176 } 177 } 178 } 179 return 0; 180 }