zoukankan      html  css  js  c++  java
  • 【BZOJ3991】寻宝游戏(虚树,DFS序,splay)

    题意:求在树中从任意点开始,经过若干个关键点回到原点的最小距离

    要求支持在线将某个点设置(取消)为关键点,以及询问答案

    n,m<=100000 len[i]<=10^9

    思路:显然是一个虚树的模型,但并不需要虚树

    其实就是求虚树的所有路径长度之和的2倍

    思考后可以发现,必定是按DFS序从小到大走,再从最大点回到最小点总路程最短

    所以只需要维护DFS序的插入,删除,前驱,后继,最大,最小,splay即可

    插入点i时找到与它DFS序相邻的点x和y,对答案有dis(x,i)+dis(y,i)-dis(x,y)的贡献

    最后加上首尾长度

      1 var t:array[0..500000,0..1]of longint;
      2     f:array[1..110000,0..17]of longint;
      3     fa,rev,size:array[0..500000]of longint;
      4     flag,dfn,id,dep,head,vet,next,len,b:array[1..500000]of longint;
      5     dis,num:array[0..500000]of int64;
      6     n,m,i,x,y,tot,root,cnt,time,z:longint;
      7     ans,v,tmp,oo,l,r:int64;
      8 
      9 procedure swap(var x,y:longint);
     10 var t:longint;
     11 begin
     12  t:=x; x:=y; y:=t;
     13 end;
     14 
     15 procedure pushup(x:longint);
     16 var l,r:longint;
     17 begin
     18  l:=t[x,0]; r:=t[x,1];
     19  size[x]:=size[l]+size[r]+1;
     20 end;
     21 
     22 procedure rotate(x:longint;var k:longint);
     23 var y,z,l,r:longint;
     24 begin
     25  y:=fa[x]; z:=fa[y];
     26  if t[y,0]=x then l:=0
     27   else l:=1;
     28  r:=l xor 1;
     29  if y<>k then
     30  begin
     31   if t[z,0]=y then t[z,0]:=x
     32    else t[z,1]:=x;
     33  end
     34   else k:=x;
     35  fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y;
     36  t[y,l]:=t[x,r]; t[x,r]:=y;
     37  pushup(y);
     38  pushup(x);
     39 end;
     40 
     41 procedure splay(x:longint;var k:longint);
     42 var y,z:longint;
     43 begin
     44  while x<>k do
     45  begin
     46   y:=fa[x]; z:=fa[y];
     47   if y<>k then
     48   begin
     49    if (t[y,0]=x)xor(t[z,0]=y) then rotate(x,k)
     50     else rotate(y,k);
     51   end
     52    else k:=x;
     53   rotate(x,k);
     54  end;
     55 end;
     56 
     57 function kth(x:longint):longint;
     58 var k,tmp:longint;
     59 begin
     60  k:=root;
     61  while k<>0 do
     62  begin
     63   tmp:=size[t[k,0]]+1;
     64   if tmp=x then exit(k)
     65    else if tmp>x then k:=t[k,0]
     66     else
     67     begin
     68      k:=t[k,1]; x:=x-tmp;
     69     end;
     70  end;
     71 end;
     72 
     73 function pred(x:int64):int64;
     74 var k:longint;
     75     last:int64;
     76 begin
     77  k:=root; last:=-oo;
     78  while k<>0 do
     79  begin
     80   if num[k]<x then begin last:=num[k]; k:=t[k,1]; end
     81    else k:=t[k,0];
     82  end;
     83  exit(last);
     84 end;
     85 
     86 function succ(x:int64):int64;
     87 var k:longint;
     88     last:int64;
     89 begin
     90  k:=root; last:=oo;
     91  while k<>0 do
     92  begin
     93   if num[k]>x then begin last:=num[k]; k:=t[k,0]; end
     94    else k:=t[k,1];
     95  end;
     96  exit(last);
     97 end;
     98 
     99 function rank(x:int64):longint;
    100 var k:longint;
    101 begin
    102  rank:=1; k:=root;
    103  while k<>0 do
    104  begin
    105   if num[k]<x then begin rank:=rank+size[t[k,0]]+1; k:=t[k,1]; end
    106    else k:=t[k,0];
    107  end;
    108 end;
    109 
    110 procedure ins(x:int64);
    111 var k,k1,k2:longint;
    112 begin
    113  k:=rank(x);
    114  k1:=kth(k-1);
    115  k2:=kth(k);
    116  splay(k1,root);
    117  splay(k2,t[root,1]);
    118  k:=t[root,1];
    119  inc(cnt); t[k,0]:=cnt; fa[cnt]:=k; size[cnt]:=1; num[cnt]:=x;
    120  inc(tot);
    121 end;
    122 
    123 procedure del(x:int64);
    124 var k,k1,k2:longint;
    125 begin
    126  k:=rank(x);
    127  k1:=kth(k-1);
    128  k2:=kth(k+1);
    129  splay(k1,root);
    130  splay(k2,t[root,1]);
    131  k1:=t[root,1]; k2:=t[k1,0];
    132  t[k1,0]:=0; size[k1]:=size[t[k1,1]]+1;
    133  fa[k2]:=0; t[k2,0]:=0; t[k2,1]:=0; size[k2]:=0; num[k2]:=0;
    134  dec(tot);
    135 end;
    136 
    137 function lca(x,y:longint):longint;
    138 var i,d:longint;
    139 begin
    140  if dep[x]<dep[y] then swap(x,y);
    141  d:=dep[x]-dep[y];
    142  for i:=0 to 17 do
    143   if d and (1<<i)>0 then x:=f[x,i];
    144  for i:=17 downto 0 do
    145   if f[x,i]<>f[y,i] then
    146   begin
    147    x:=f[x,i]; y:=f[y,i];
    148   end;
    149  if x=y then exit(x);
    150  exit(f[x,0]);
    151 end;
    152 
    153 function query(x,y:longint):int64;
    154 var q:longint;
    155 begin
    156  q:=lca(x,y);
    157  exit(dis[x]+dis[y]-2*dis[q]);
    158 end;
    159 
    160 procedure add(a,b,c:longint);
    161 begin
    162  inc(tot);
    163  next[tot]:=head[a];
    164  vet[tot]:=b;
    165  len[tot]:=c;
    166  head[a]:=tot;
    167 end;
    168 
    169 procedure dfs(u:longint);
    170 var i,e,v:longint;
    171 begin
    172  flag[u]:=1;
    173  inc(time); dfn[u]:=time; id[time]:=u;
    174  for i:=1 to 17 do
    175  begin
    176   if dep[u]<1<<i then break;
    177   f[u,i]:=f[f[u,i-1],i-1];
    178  end;
    179  e:=head[u];
    180  while e<>0 do
    181  begin
    182   v:=vet[e];
    183   if flag[v]=0 then
    184   begin
    185    dep[v]:=dep[u]+1;
    186    dis[v]:=dis[u]+len[e];
    187    f[v,0]:=u;
    188    dfs(v);
    189   end;
    190   e:=next[e];
    191  end;
    192 end;
    193 
    194 begin
    195  assign(input,'bzoj3991.in'); reset(input);
    196  assign(output,'bzoj3991.out'); rewrite(output);
    197  readln(n,m);
    198  for i:=1 to n-1 do
    199  begin
    200   readln(x,y,z);
    201   add(x,y,z);
    202   add(y,x,z);
    203  end;
    204  dfs(1);
    205  oo:=1<<60;
    206  num[1]:=oo; t[1,0]:=2; size[1]:=2;
    207  num[2]:=-oo; fa[2]:=1; size[2]:=1;
    208  root:=1; cnt:=2; tot:=2;
    209  for i:=1 to m do
    210  begin
    211   readln(x);
    212   if b[x]=0 then begin v:=1; ins(dfn[x]); end
    213    else begin v:=-1; del(dfn[x]); end;
    214   b[x]:=b[x] xor 1;
    215   l:=pred(dfn[x]);
    216   r:=succ(dfn[x]);
    217   if l<>-oo then ans:=ans+v*query(id[l],x);
    218   if r<>oo then ans:=ans+v*query(id[r],x);
    219   if (l<>-oo)and(r<>oo) then ans:=ans-v*query(id[l],id[r]);
    220   tmp:=0;
    221   if tot>3 then
    222   begin
    223    l:=kth(2);
    224    r:=kth(tot-1);
    225    tmp:=query(id[num[l]],id[num[r]]);
    226   end;
    227   writeln(ans+tmp);
    228  end;
    229  close(input);
    230  close(output);
    231 end.
  • 相关阅读:
    SpringBoot1.x与监控(六)
    p6spy打印SQL
    django-forms组件
    博客园美化首页随笔同时一天发布内容分开分开版块展示
    django自关联,auth模块
    博客园美化首页随笔展示美化
    原生js获得八种方式,事件操作
    UVa 1347 Tour
    UVA 11527 Unique Snowflakes
    HDU1242 Rescue
  • 原文地址:https://www.cnblogs.com/myx12345/p/6394399.html
Copyright © 2011-2022 走看看