• 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
     
  • 相关阅读:
    自己回答自己的问题
    作业5 四则运算 测试与封装 5.1 5.2
    2015430 加法阶段一的封装测试
    20150423 提问2
    Java 泛型中的<? super T>和<? extends T>
    ssh 查看端口占用
    Java 回调
    SpringMVC4+MyBaits3配置
    Selenium 远程执行和监听类
    Intellij idea主题
  • 原文地址:https://www.cnblogs.com/GhostReach/p/7001661.html
Copyright © 2020-2023  润新知