您的位置:首页 > 其它

【BZOJ3991】寻宝游戏(虚树,DFS序,splay)

2017-02-13 16:35 274 查看

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

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

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.

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: