JZOJ5143:无心行挽
Description
“What’s left to do when we’ve lost all hope?”
“若内心万念俱灰,是否注定无心行挽?”
------来自网易云音乐<Golden Leaves-Passenger>
不必做好输掉一切的准备。
所以,无畏结局。
在尽头,已经不能再做什么,来挽回。
在尽头,所有的一切都走向简化,没有了重复,没有了错杂,只剩下一片废墟。
就是说,世界曾是一副错杂的无向图,而在尽头,它已成为一个没有环的无向连通图,也就是说已成为一棵树。
这棵树有n个节点,有n-1条边,每条边的长度都是1。
给出q组询问,每组询问会给出k个关键点,设f(u)表示所有关键点中离点u最近的关键点离u的距离,求出最大的f(u)。
“若内心万念俱灰,是否注定无心行挽?”
------来自网易云音乐<Golden Leaves-Passenger>
不必做好输掉一切的准备。
所以,无畏结局。
在尽头,已经不能再做什么,来挽回。
在尽头,所有的一切都走向简化,没有了重复,没有了错杂,只剩下一片废墟。
就是说,世界曾是一副错杂的无向图,而在尽头,它已成为一个没有环的无向连通图,也就是说已成为一棵树。
这棵树有n个节点,有n-1条边,每条边的长度都是1。
给出q组询问,每组询问会给出k个关键点,设f(u)表示所有关键点中离点u最近的关键点离u的距离,求出最大的f(u)。
Input
第一行两个正整数n和q表示树的节点个数以及询问个数
接下来n-1行每行三个数u,v描述一条边,表示u和v之间有一条长度为1的无向边
接下来q组询问,每组询问第一行一个正整数k表示这组询问中关键点的个数,第二行k个正整数,表示这组询问的k个关键点。
Output
共q行,第i行对于第i组询问给出答案,详情见题目描述。
Sample Input
7 5
5 4
6 5
7 3
7 4
1 5
2 4
1
4
1
6
4
6 5 7 2
5
1 5 4 3 7
2
2 3
Sample Output
2
4
1
1
3
HINT
令S表示所有询问里k的和
对于20%的数据,1<=n,q,S<=3000
对于另外30%的数据,每组询问的k<=5
对于另外10%的数据,给出的树是一条链
对于另外20%的数据,1<=q<=10
对于100%的数据,1<=n,q,S<=100000
题解:
我们可以把树中的点根据距离其最近的关键点是什么来分类,即求出每个关键点“掌控”了哪些点。
建出虚树后,先从下往上做一次树形DP,求出虚树中每一个点往下距离最近的关键点;在从上往下做一次DFS,求出虚树中的每个点是被哪个关键点“掌控”(即比较上下的关键点哪个更近)。
对虚树中每一条边进行求解,根据距离两端的关键点的距离将一条边分为上下两份。
对于上方那份,用线段树求出其对应DPS序上最深的点,更新答案;对于下方那份,用倍增处理链上以及链上向外的子树中距离关键点最远的点,更新答案。
代码:
1 uses math; 2 const 3 maxn=300050; 4 inf=1000000000; 5 var 6 w:array[0..3*maxn,1..2]of longint; 7 bel,dep,x,y,ans,t,size,key,cle,mxd,wz,ff:array[0..maxn]of longint; 8 tt:array[0..maxn,-2..2]of longint; 9 pos,mx:array[0..maxn,1..2]of longint; 10 st,bz:array[0..maxn,0..20]of longint; 11 i,j,k,tot,tt2:longint; 12 n,m,len,a,b,top,cnt,anss:longint; 13 procedure init(a,b:longint); 14 begin 15 w[len,1]:=b; w[len,2]:=0; 16 if w[a,2]=0 then w[a,2]:=len else w[w[a,1],2]:=len; 17 w[a,1]:=len; inc(len); 18 end; 19 procedure sort(l,r:longint); 20 var i,j,a,b:longint; 21 begin 22 i:=l; j:=r; a:=pos[x[(l+r)div 2],1]; 23 repeat 24 while pos[x[i],1]<a do inc(i); 25 while a<pos[x[j],1] do dec(j); 26 if not(i>j) then 27 begin 28 b:=x[i]; x[i]:=x[j]; x[j]:=b; 29 inc(i); dec(j); 30 end; 31 until i>j; 32 if l<j then sort(l,j); 33 if i<r then sort(i,r); 34 end; 35 procedure dfs(a,fa:longint); 36 var tt:longint; 37 begin 38 mx[a,1]:=0; mx[a,2]:=0; mxd[a]:=dep[a]; 39 tt:=w[a,2]; inc(len); pos[a,1]:=len; wz[len]:=a; size[a]:=1; 40 while tt<>0 do 41 begin 42 if w[tt,1]<>fa then 43 begin 44 dep[w[tt,1]]:=dep[a]+1; 45 st[w[tt,1],0]:=a; dfs(w[tt,1],a); 46 inc(size[a],size[w[tt,1]]); 47 if(mx[a,1]=0)or(mxd[w[tt,1]]>mxd[mx[a,1]])then 48 begin mx[a,2]:=mx[a,1]; mx[a,1]:=w[tt,1]; mxd[a]:=mxd[w[tt,1]]; end 49 else if(mx[a,2]=0)or(mxd[w[tt,1]]>mxd[mx[a,2]])then mx[a,2]:=w[tt,1]; 50 end; 51 tt:=w[tt,2]; 52 end; 53 pos[a,2]:=len; 54 end; 55 procedure dfss(a,fa:longint); 56 var tt:longint; 57 begin 58 if fa=0 then bz[a,0]:=0 else 59 begin 60 if mx[fa,1]=a then tt:=mx[fa,2] else tt:=mx[fa,1]; 61 if tt=0 then bz[a,0]:=1 else bz[a,0]:=1+mxd[tt]-dep[fa]; 62 end; 63 tt:=w[a,2]; 64 while tt<>0 do 65 begin 66 if w[tt,1]<>fa then dfss(w[tt,1],a); 67 tt:=w[tt,2]; 68 end; 69 end; 70 function lca(a,b:longint):longint; 71 var i:longint; 72 begin 73 if dep[a]<dep[b] then begin i:=a; a:=b; b:=i; end; 74 for i:=20 downto 0 do 75 if dep[st[a,i]]>=dep[b] then a:=st[a,i]; 76 if a=b then exit(a); 77 for i:=20 downto 0 do 78 if st[a,i]<>st[b,i] then begin a:=st[a,i]; b:=st[b,i]; end; 79 exit(st[a,0]); 80 end; 81 function get(fa,a:longint):Longint; 82 var i:longint; 83 begin 84 for i:=20 downto 0 do 85 if dep[st[a,i]]>dep[fa] then a:=st[a,i]; 86 exit(a); 87 end; 88 function dis(a,b:longint):longint; 89 begin exit(dep[a]+dep[b]-2*dep[lca(a,b)]); end; 90 procedure dfs1(a:longint); 91 var tt:longint; 92 begin 93 tt:=w[a,2]; 94 if key[a]=1 then bel[a]:=a else bel[a]:=inf; 95 while (tt<>0) do 96 begin 97 dfs1(w[tt,1]); 98 if(bel[w[tt,1]]<>inf)and((bel[a]=inf) 99 or(dis(bel[w[tt,1]],a)<dis(bel[a],a)) 100 or((dis(bel[w[tt,1]],a)=dis(bel[a],a))and(bel[w[tt,1]]<bel[a]))) 101 then bel[a]:=bel[w[tt,1]]; 102 tt:=w[tt,2]; 103 end; 104 end; 105 procedure dfs2(a,fa:longint); 106 var tt:longint; 107 begin 108 ff[a]:=0; 109 if(a<>0)and((dis(bel[fa],a)<dis(a,bel[a])) 110 or((dis(bel[fa],a)=dis(a,bel[a]))and(bel[fa]<bel[a]))) 111 then begin bel[a]:=bel[fa]; ff[a]:=1; end; 112 tt:=w[a,2]; 113 while tt<>0 do 114 begin dfs2(w[tt,1],a); tt:=w[tt,2]; end; 115 end; 116 function work(a,x:longint):longint; 117 var i,j,y:longint; 118 begin 119 if x=0 then exit(0); 120 j:=0; y:=0; 121 for i:=20 downto 0 do 122 begin 123 if j+(1<<i)<=x then 124 begin y:=max(y,j+bz[a,i]); a:=st[a,i]; j:=j+(1<<i); end; 125 end; 126 exit(y); 127 end; 128 procedure build(l,r,fa:longint); 129 var mid,x:longint; 130 begin 131 inc(tot); x:=tot; tt[x,1]:=l; tt[x,2]:=r; 132 if tt[x,1]=tt[fa,1] then tt[fa,-1]:=x else tt[fa,-2]:=x; 133 if l=r then begin tt[x,0]:=dep[wz[l]]; exit; end; 134 mid:=(l+r)>>1; 135 build(l,mid,x); build(mid+1,r,x); 136 tt[x,0]:=max(tt[tt[x,-1],0],tt[tt[x,-2],0]); 137 end; 138 function find(x,l,r:longint):longint; 139 var ll,rr,mid:longint; 140 begin 141 if l>r then exit(0); 142 ll:=tt[x,1]; rr:=tt[x,2]; 143 if(ll=l)and(rr=r)then exit(tt[x,0]); 144 mid:=(ll+rr)>>1; 145 if r<=mid then exit(find(tt[x,-1],l,r)); 146 if l>mid then exit(find(tt[x,-2],l,r)); 147 exit(max(find(tt[x,-1],l,mid),find(tt[x,-2],mid+1,r))); 148 end; 149 procedure solve(a,fa:longint); 150 var tt,sum,aa,i,x,md,dis1,dis2,z:longint; 151 begin 152 if fa=0 then 153 begin 154 md:=work(a,dep[a]-dep[1]); 155 ans[bel[a]]:=max(ans[bel[a]],md+dis(a,bel[a])); 156 end else 157 begin 158 tt:=get(fa,a); aa:=a; 159 if bel[a]=bel[fa] then 160 begin 161 if ff[a]=1 then 162 begin 163 md:=find(1,pos[tt,1],pos[a,1]-1); 164 md:=max(md,find(1,pos[a,2]+1,pos[tt,2])); 165 ans[bel[a]]:=max(ans[bel[a]],md-dep[fa]+dis(fa,bel[a])); 166 end else 167 begin 168 md:=work(a,dep[a]-dep[tt]); 169 ans[bel[a]]:=max(ans[bel[a]],md+dis(a,bel[a])); 170 end; 171 end else 172 begin 173 dis1:=dis(fa,bel[fa]); dis2:=dis(a,bel[a]); 174 for i:=20 downto 0 do 175 begin 176 if dep[st[aa,i]]<dep[tt] then continue; 177 if(dep[a]-dep[st[aa,i]]+dis2<dep[st[aa,i]]-dep[fa]+dis1) 178 or((dep[a]-dep[st[aa,i]]+dis2=dep[st[aa,i]]-dep[fa]+dis1) 179 and(bel[a]<bel[fa]))then aa:=st[aa,i]; 180 end; 181 md:=work(a,dep[a]-dep[aa]); 182 ans[bel[a]]:=max(ans[bel[a]],dis(a,bel[a])+md); 183 md:=find(1,pos[tt,1],pos[aa,1]-1); 184 md:=max(md,find(1,pos[aa,2]+1,pos[tt,2])); 185 ans[bel[fa]]:=max(ans[bel[fa]],md-dep[tt]+dis(tt,bel[fa])); 186 end; 187 end; 188 md:=dep[a]; tt:=w[a,2]; x:=pos[a,1]-1; 189 while tt<>0 do 190 begin 191 z:=get(a,w[tt,1]); 192 md:=max(md,find(1,x+1,pos[z,1]-1)); 193 x:=pos[z,2]; solve(w[tt,1],a); tt:=w[tt,2]; 194 end; 195 md:=max(md,find(1,x+1,pos[a,2])); 196 ans[bel[a]]:=max(ans[bel[a]],md-dep[a]+dis(a,bel[a])); 197 end; 198 begin 199 assign(input,'do.in'); reset(input); 200 assign(output,'do.out'); rewrite(output); 201 readln(n,m); len:=n+1; 202 for i:=1 to n-1 do 203 begin readln(a,b); init(a,b); init(b,a); end; 204 init(0,1); init(1,0); dep[0]:=1; len:=0; dfs(0,0); dfss(0,0); 205 for j:=1 to 20 do for i:=1 to n do 206 st[i,j]:=st[st[i,j-1],j-1]; 207 for j:=1 to 20 do for i:=1 to n do 208 if st[i,j-1]>0 then bz[i,j]:=max(bz[i,j-1],(1<<(j-1))+bz[st[i,j-1],j-1]); 209 build(1,n+1,0); 210 fillchar(key,sizeof(key),0); 211 fillchar(bel,sizeof(bel),0); 212 fillchar(ans,sizeof(ans),0); 213 fillchar(w,sizeof(w),0); 214 for i:=1 to m do 215 begin 216 readln(cnt); 217 for j:=1 to cnt do 218 begin read(x[j]); y[j]:=x[j]; cle[j]:=x[j]; key[x[j]]:=1; end; 219 sort(1,cnt); top:=1; t[top]:=0; len:=n+1; cle[0]:=cnt+1; cle[cnt+1]:=0; 220 for j:=1 to cnt do 221 begin 222 tt2:=lca(x[j],t[top]); 223 while dep[tt2]<dep[t[top]] do 224 begin 225 if dep[t[top-1]]<=dep[tt2] then 226 begin 227 init(tt2,t[top]); dec(top); 228 if t[top]<>tt2 then 229 begin inc(top); t[top]:=tt2; inc(cle[0]); cle[cle[0]]:=tt2; end; 230 break; 231 end; 232 init(t[top-1],t[top]); dec(top); 233 end; 234 inc(top); t[top]:=x[j]; 235 end; 236 while top>1 do 237 begin init(t[top-1],t[top]); dec(top); end; 238 dfs1(0); dfs2(0,0); solve(w[w[0,2],1],0); 239 anss:=0; 240 for j:=1 to cnt do anss:=max(anss,ans[y[j]]); writeln(anss); 241 for j:=1 to cle[0] do 242 begin 243 w[cle[j],2]:=0; key[cle[j]]:=0; 244 bel[cle[j]]:=inf; ans[cle[j]]:=0; 245 end; 246 end; 247 close(input); close(output); 248 end.