zoukankan      html  css  js  c++  java
  • bzoj3572: [Hnoi2014]世界树

    3572: [Hnoi2014]世界树

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 1325  Solved: 732
    [Submit][Status][Discuss]

    Description

    世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界。在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息、持续运转的根本基石。
    世界树的形态可以用一个数学模型来描述:世界树中有n个种族,种族的编号分别从1到n,分别生活在编号为1到n的聚居地上,种族的编号与其聚居地的编号相同。有的聚居地之间有双向的道路相连,道路的长度为1。保证连接的方式会形成一棵树结构,即所有的聚居地之间可以互相到达,并且不会出现环。定义两个聚居地之间的距离为连接他们的道路的长度;例如,若聚居地a和b之间有道路,b和c之间有道路,因为每条道路长度为1而且又不可能出现环,所卧a与c之间的距离为2。
    出于对公平的考虑,第i年,世界树的国王需要授权m[i]个种族的聚居地为临时议事处。对于某个种族x(x为种族的编号),如果距离该种族最近的临时议事处为y(y为议事处所在聚居地的编号),则种族x将接受y议事处的管辖(如果有多个临时议事处到该聚居地的距离一样,则y为其中编号最小的临时议事处)。
    现在国王想知道,在q年的时间里,每一年完成授权后,当年每个临时议事处将会管理多少个种族(议事处所在的聚居地也将接受该议事处管理)。 现在这个任务交给了以智慧著称的灵长类的你:程序猿。请帮国王完成这个任务吧。

    Input

    第一行为一个正整数n,表示世界树中种族的个数。
    接下来n-l行,每行两个正整数x,y,表示x聚居地与y聚居地之间有一条长度为1的双
    向道路。接下来一行为一个正整数q,表示国王询问的年数。
    接下来q块,每块两行:
    第i块的第一行为1个正整数m[i],表示第i年授权的临时议事处的个数。
    第i块的第二行为m[i]个正整数h[l]、h[2]、…、h[m[i]],表示被授权为临时议事处的聚居地编号(保证互不相同)。

    Output

    输出包含q行,第i行为m[i]个整数,该行的第j(j=1,2…,,m[i])个数表示第i年被授权的聚居地h[j]的临时议事处管理的种族个数。

    Sample Input

    10
    2 1
    3 2
    4 3
    5 4
    6 1
    7 3
    8 3
    9 4
    10 1
    5
    2
    6 1
    5
    2 7 3 6 9
    1
    8
    4
    8 7 10 3
    5
    2 9 3 5 8

    Sample Output

    1 9
    3 1 4 1 1
    10
    1 1 3 5
    4 1 3 1 1

    HINT

    N<=300000, q<=300000,m[1]+m[2]+…+m[q]<=300000

     
    题解
    建立虚树,因为虚树上的点并不都是给出的点,所以要从下向上再从上向下扫两遍,求出数组bel,即距离虚树上每个点最近的给出的点。然后对于每一条虚边上的点,控制它的一定是两端点的bel,二分(其实是在倍增出的祖先数组中跳)出分界点,然后算一下。具体细节看代码吧,感觉还是又不少要注意的地方
    //因为扫的顺序搞错了吃了好几发WA
      1 program j01;
      2 const maxn=300086;
      3 var f:array[0..maxn,0..20]of longint;
      4     fa,dfn,h,head,bin,id,ans,dep:array[0..maxn]of longint;
      5     q,next:array[0..2*maxn]of longint;
      6     st,cnt,bel,rem,size,tmp,del:array[0..maxn]of longint;
      7     vis:array[0..maxn]of boolean;
      8     n,m,u,v,i,tt,time:longint;
      9 
     10 procedure add(u,v:longint);
     11 begin
     12   inc(tt);q[tt]:=v;next[tt]:=head[u];head[u]:=tt;
     13 end;
     14 
     15 procedure swap(var a,b:longint);
     16 var c:longint;
     17 begin
     18   c:=a;a:=b;b:=c;
     19 end;
     20 
     21 procedure dfs(i:longint);
     22 var j:longint;
     23 begin
     24   for j:=1 to bin[dep[i]] do
     25     f[i,j]:=f[f[i,j-1],j-1];
     26   size[i]:=1;inc(time);dfn[i]:=time;
     27   j:=head[i];
     28   while j>0 do
     29   begin
     30     if q[j]<>f[i,0] then
     31     begin
     32       dep[q[j]]:=dep[i]+1;
     33       f[q[j],0]:=i;
     34       dfs(q[j]);
     35       inc(size[i],size[q[j]]);
     36     end;
     37     j:=next[j];
     38   end;
     39 end;
     40 
     41 function cmp(a,b:longint):boolean;
     42 begin
     43   exit(dfn[a]<dfn[b]);
     44 end;
     45 
     46 procedure sort(l,r:longint);
     47 var i,j,x:longint;
     48 begin
     49   i:=l;j:=r;x:=h[(i+j)div 2];
     50   repeat
     51     while cmp(h[i],x) do inc(i);
     52     while cmp(x,h[j]) do dec(j);
     53     if i<=j then
     54     begin
     55       swap(h[i],h[j]);swap(id[i],id[j]);
     56       inc(i);dec(j);
     57     end;
     58   until i>j;
     59   if i<r then sort(i,r);
     60   if l<j then sort(l,j);
     61 end;
     62 
     63 function lca(u,v:longint):longint;
     64 var d,i:longint;
     65 begin
     66   if u=v then exit(u);
     67   if dep[u]<dep[v] then swap(u,v);
     68   d:=dep[u]-dep[v];
     69   for i:=bin[d] downto 0 do
     70     if d and(1 shl i)>0 then u:=f[u,i];
     71   for i:=bin[dep[u]] downto 0 do
     72     if f[u,i]<>f[v,i] then
     73     begin
     74       u:=f[u,i];v:=f[v,i];
     75     end;
     76   if u=v then exit(u) else exit(f[u,0]);
     77 end;
     78 
     79 procedure ins(u,v:longint);
     80 begin
     81   fa[v]:=u;
     82 end;
     83 
     84 procedure qsort(l,r:longint);
     85 var i,j,x:longint;
     86 begin
     87   i:=l;j:=r;x:=tmp[(i+j)div 2];
     88   repeat
     89     while cmp(tmp[i],x) do inc(i);
     90     while cmp(x,tmp[j]) do dec(j);
     91     if i<=j then
     92     begin
     93       swap(tmp[i],tmp[j]);
     94       inc(i);dec(j);
     95     end;
     96   until i>j;
     97   if i<r then qsort(i,r);
     98   if l<j then qsort(l,j);
     99 end;
    100 
    101 function dis(u,v:longint):longint;
    102 begin
    103   exit(dep[u]+dep[v]-2*dep[lca(u,v)]);
    104 end;
    105 
    106 
    107 procedure sol(u,v:longint);
    108 var i,t1,t2,x,mid,nxt:longint;
    109 begin
    110   x:=v;
    111   for i:=bin[dep[v]] downto 0 do
    112     if dep[f[x,i]]>dep[u] then x:=f[x,i];
    113   dec(rem[u],size[x]);
    114   if bel[u]=bel[v] then
    115   begin
    116     inc(cnt[bel[u]],size[x]-size[v]);
    117     exit;
    118   end;
    119   mid:=v;
    120   for i:=bin[dep[v]] downto 0 do
    121   begin
    122     nxt:=f[mid,i];
    123     if dep[nxt]<=dep[u] then continue;
    124     t1:=dis(bel[u],nxt);t2:=dis(bel[v],nxt);
    125     if(t1>t2)or((t1=t2)and(bel[u]>bel[v])) then mid:=nxt;
    126   end;
    127   inc(cnt[bel[u]],size[x]-size[mid]);
    128   inc(cnt[bel[v]],size[mid]-size[v]);
    129 end;
    130 
    131 procedure solve;
    132 var i,j,ff,top,x,k,tot,t1,t2:longint;
    133 begin
    134   readln(k);
    135   for i:=1 to k do
    136   begin
    137     read(h[i]);vis[h[i]]:=true;cnt[h[i]]:=0;id[i]:=i;
    138   end;
    139   sort(1,k);
    140   st[1]:=1;top:=1;tmp[1]:=1;tot:=1;
    141   if vis[1] then bel[1]:=1 else bel[1]:=0;
    142   for i:=1 to k do
    143   begin
    144     if h[i]=st[top] then continue;
    145     x:=h[i];ff:=lca(x,st[top]);
    146     while(top>1)and(dep[ff]<dep[st[top-1]]) do
    147     begin
    148       ins(st[top-1],st[top]);dec(top);
    149     end;
    150     if st[top]<>ff then ins(ff,st[top]);
    151     if st[top-1]<>ff then
    152     begin
    153       if tmp[tot]<>ff then
    154       begin
    155         inc(tot);tmp[tot]:=ff;
    156       end;
    157       st[top]:=ff;
    158       if vis[ff] then bel[ff]:=ff else bel[ff]:=0;
    159     end else dec(top);
    160     inc(top);st[top]:=x;inc(tot);tmp[tot]:=x;
    161     if vis[x] then bel[x]:=x else bel[x]:=0;
    162   end;
    163   while top>1 do
    164   begin
    165     ins(st[top-1],st[top]);dec(top);
    166   end;
    167   qsort(1,tot);
    168   for j:=tot downto 2 do
    169   begin
    170     i:=tmp[j];
    171     t1:=dis(fa[i],bel[i]);t2:=dis(fa[i],bel[fa[i]]);
    172     if(t1<t2)or((t1=t2)and(bel[i]<bel[fa[i]]))or(bel[fa[i]]=0) then
    173       bel[fa[i]]:=bel[i];
    174   end;
    175   for j:=1 to tot do
    176   begin
    177     i:=tmp[j];
    178     rem[i]:=size[i];if i=1 then continue;
    179     t1:=dis(i,bel[i]);t2:=dis(i,bel[fa[i]]);
    180     if(t1>t2)or((t1=t2)and(bel[fa[i]]<bel[i]))or(bel[i]=0) then
    181       bel[i]:=bel[fa[i]];
    182   end;
    183   for i:=2 to tot do
    184     sol(fa[tmp[i]],tmp[i]);
    185   for i:=1 to tot do inc(cnt[bel[tmp[i]]],rem[tmp[i]]);
    186   for i:=1 to k do ans[id[i]]:=cnt[h[i]];
    187   for i:=1 to k do vis[h[i]]:=false;
    188   for i:=1 to k do write(ans[i],' ');writeln;
    189 end;
    190 
    191 begin
    192   //assign(input,'1.in');reset(input);
    193   readln(n);
    194   fillchar(head,sizeof(head),0);
    195   for i:=1 to n-1 do
    196   begin
    197     readln(u,v);add(u,v);add(v,u);
    198   end;
    199   bin[1]:=0;
    200   for i:=2 to n do
    201     if i and(i-1)=0 then bin[i]:=bin[i-1]+1 else bin[i]:=bin[i-1];
    202   dep[1]:=0;time:=0;
    203   dfs(1);
    204   readln(m);
    205   for i:=1 to m do
    206   begin
    207     solve;
    208   end;
    209 end.
    View Code
  • 相关阅读:
    Webpack4 入门手册(共 18 章)下
    npm(Node Package Manager)
    C#(99):C# 5.0 新特性(.NET Framework 4.5 与 Visual Studio 2012 )
    C#(99):四、Async和Await使异步编程更简单
    C#(99):三、.NET 4.0基于任务的异步模式(TAP),推荐使用
    C#(99):二、.NET 2.0基于事件的异步编程模式(EAP)
    C#(99):一、.NET 1.0 异步编程模型(APM)
    VS中的代码段功能
    VS在C#类文件头部添加文件注释的方法
    C#(99):C# 语言历史版本特性(C# 1.0到C# 8.0汇总)
  • 原文地址:https://www.cnblogs.com/oldjang/p/6392878.html
Copyright © 2011-2022 走看看