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)。

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.
View Code
 
posted @ 2017-06-13 15:46  GhoStreach  阅读(2322)  评论(0编辑  收藏  举报