• bzoj3611


    会构建虚树之后就是noip提高组的题目了
    稍微难一点的是求代价和,只要注意按一个方向避免重复计算贡献即可

      1 const inf=100000000;
      2 type node=record
      3        po,next:longint;
      4      end;
      5 
      6 var mi,mx,fa,p,q,size,d,a,b:array[0..1000010] of longint;
      7     e:array[0..2000010] of node;
      8     f:array[0..1000010] of int64;
      9     v:array[0..1000010] of boolean;
     10     anc:array[0..1000010,0..21] of longint;
     11     ans2,ans3,z,t,h,i,len,n,m,s,j,x,y:longint;
     12     dis,ans1:int64;
     13 
     14 procedure add(x,y:longint);
     15   begin
     16     inc(len);
     17     e[len].po:=y;
     18     e[len].next:=p[x];
     19     p[x]:=len;
     20   end;
     21 
     22 procedure swap(var a,b:longint);
     23   var c:longint;
     24   begin
     25     c:=a;
     26     a:=b;
     27     b:=c;
     28   end;
     29 
     30 function max(a,b:longint):longint;
     31   begin
     32     if a>b then exit(a) else exit(b);
     33   end;
     34 
     35 function min(a,b:longint):longint;
     36   begin
     37     if a>b then exit(b) else exit(a);
     38   end;
     39 
     40 procedure dfs(x:longint);
     41   var i,y:longint;
     42   begin
     43     inc(h);
     44     a[x]:=h;
     45     i:=p[x];
     46     while i<>0 do
     47     begin
     48       y:=e[i].po;
     49       if fa[x]<>y then
     50       begin
     51         fa[y]:=x;
     52         anc[y,0]:=x;
     53         d[y]:=d[x]+1;
     54         dfs(y);
     55       end;
     56       i:=e[i].next;
     57     end;
     58   end;
     59 
     60 procedure sort(l,r:longint);
     61   var i,j,x:longint;
     62   begin
     63     i:=l;
     64     j:=r;
     65     x:=a[b[(l+r) shr 1]];
     66     repeat
     67       while a[b[i]]<x do inc(i);
     68       while x<a[b[j]] do dec(j);
     69       if not(i>j) then
     70       begin
     71         swap(b[i],b[j]);
     72         inc(i);
     73         dec(j);
     74       end;
     75     until i>j;
     76     if l<j then sort(l,j);
     77     if i<r then sort(i,r);
     78   end;
     79 
     80 function lca(x,y:longint):longint;
     81   var i,p:longint;
     82   begin
     83     if x=y then exit(x);
     84     if d[x]<d[y] then swap(x,y);
     85     p:=trunc(ln(d[x])/ln(2));
     86     if d[x]>d[y] then
     87       for i:=p downto 0 do
     88         if d[x]-1 shl i>=d[y] then x:=anc[x,i];
     89     if x=y then exit(x);
     90     for i:=p downto 0 do
     91       if (anc[y,i]<>anc[x,i]) then
     92       begin
     93         x:=anc[x,i];
     94         y:=anc[y,i];
     95       end;
     96     exit(fa[x]);
     97   end;
     98 
     99 procedure dp(x:longint);
    100   var i,y:longint;
    101   begin
    102     f[x]:=0;
    103     if v[x] then
    104     begin
    105       size[x]:=1;  //size[]表示虚树中包含的关键点个数
    106       mi[x]:=0;    
    107       mx[x]:=0;
    108     end
    109     else begin
    110       size[x]:=0;
    111       mi[x]:=inf;
    112       mx[x]:=-inf;
    113     end;
    114     i:=p[x];
    115     while i<>0 do
    116     begin
    117       y:=e[i].po;
    118       dp(y);
    119       dis:=d[y]-d[x];
    120       ans1:=ans1+(f[x]+int64(size[x])*dis)*int64(size[y])+f[y]*int64(size[x]);
    121       size[x]:=size[x]+size[y];
    122       f[x]:=f[x]+f[y]+int64(size[y])*dis;
    123       ans2:=min(ans2,mi[x]+dis+mi[y]);
    124       ans3:=max(ans3,mx[x]+dis+mx[y]);
    125       mx[x]:=max(mx[x],dis+mx[y]);
    126       mi[x]:=min(mi[x],dis+mi[y]);
    127       i:=e[i].next;
    128     end;
    129     p[x]:=0;
    130   end;
    131 
    132 begin
    133   readln(n);
    134   for i:=1 to n-1 do
    135   begin
    136     readln(x,y);
    137     add(x,y);
    138     add(y,x);
    139   end;
    140   dfs(1);
    141   t:=trunc(ln(n)/ln(2));
    142   for  i:=1 to t do 
    143     for j:=1 to n do 
    144     begin
    145       y:=anc[j,i-1];
    146       if  y<>0 then anc[j,i]:=anc[y,i-1];
    147     end;
    148   fillchar(p,sizeof(p),0);
    149   readln(m);
    150   for i:=1 to m do
    151   begin
    152     readln(s);
    153     for j:=1 to s do
    154     begin
    155       read(b[j]);
    156       v[b[j]]:=true;
    157     end;
    158     readln;
    159     sort(1,s);
    160     ans1:=0;
    161     ans2:=inf;
    162     ans3:=0;
    163     len:=0;
    164     t:=1;
    165     q[1]:=1;
    166     for j:=1 to s do
    167     begin
    168       x:=b[j];
    169       z:=lca(x,q[t]);
    170       while d[z]<d[q[t]] do
    171       begin
    172         if d[z]>=d[q[t-1]] then
    173         begin
    174           add(z,q[t]);
    175           dec(t);
    176           if q[t]<>z then
    177           begin
    178             inc(t);
    179             q[t]:=z;
    180           end;
    181           break;
    182         end;
    183         add(q[t-1],q[t]);
    184         dec(t);
    185       end;
    186       if q[t]<>x then
    187       begin
    188         inc(t);
    189         q[t]:=x;
    190       end;
    191     end;
    192     while t>1 do
    193     begin
    194       add(q[t-1],q[t]);
    195       dec(t);
    196     end;
    197     dp(1);
    198     writeln(ans1,' ',ans2,' ',ans3);
    199     for j:=1 to s do
    200       v[b[j]]:=false;
    201   end;
    202 end.
    View Code
  • 相关阅读:
    3、Find and run the whalesay image
    1、docker初涉
    Java之ThreadLocal原理分析
    Java之Synchronized和ReentrantLock锁机制的比较
    Java之动态代理的实现及原理
    Java之atomic包的原理及分析
    深入理解Java内存模型-volatile
    Java WeakReference
    JavaScript 事件的冒泡,委派
    JavaScript Date删除添加员工信息练习
  • 原文地址:https://www.cnblogs.com/phile/p/4472965.html
Copyright © 2020-2023  润新知