zoukankan      html  css  js  c++  java
  • 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
     
  • 相关阅读:
    免费的视频、音频转文本
    Errors are values
    Codebase Refactoring (with help from Go)
    Golang中的坑二
    Cleaner, more elegant, and wrong(msdn blog)
    Cleaner, more elegant, and wrong(翻译)
    Cleaner, more elegant, and harder to recognize(翻译)
    vue控制父子组件渲染顺序
    computed 和 watch 组合使用,监听数据全局数据状态
    webstorm破解方法
  • 原文地址:https://www.cnblogs.com/GhostReach/p/7001661.html
Copyright © 2011-2022 走看看