排队
题目描述
数据范围
题解
用 dfs 遍历一遍整棵树,先遍历编号大的儿子,再遍历编号小的儿子,得出 dfs 序(简称 dfx ),定义优先级更优仅当 dfx 更大时,那么在放人的时候先放入优先级更优的空房间显然是满足题目条件的。
那么我们可以用一个堆来维护空房间(大顶堆,按照优先级来维护,一开始堆内只有叶子节点),每次把堆顶取出(即当前优先级最优的空房间),如果可以把它的父亲放入堆中,那就放进堆内维护一下。(可以把一个节点的父亲放入堆中当且仅当他的父亲不在堆内且他的父亲为空房间)
以上是
1
号操作的做法。
对于
Code(Pascal)
var
fz,fd:array[-1..210000] of boolean;
fa,en,dfx,yx,d,sd:array[-1..210000] of int64;
bj:array[0..210000,1..2] of int64;
f:array[0..110000,0..20] of int64;
n,m,x,cqy,l,i,op,t,kkk,ans,p,wz:longint;
procedure qsort(l,r:longint);
var
i,j,m,mm:longint;
begin
i:=l;
j:=r;
m:=bj[(l+r) div 2,1];
mm:=bj[(l+r) div 2,2];
repeat
while (bj[i,1]<m) or ((bj[i,1]=m) and (bj[i,2]>mm)) do inc(i);
while (bj[j,1]>m) or ((bj[j,1]=m) and (bj[j,2]<mm)) do dec(j);
if i<=j then
begin
bj[0]:=bj[i];
bj[i]:=bj[j];
bj[j]:=bj[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
procedure up(o:longint);
var
y:longint;
begin
while (o>1) and (yx[d[o]]>yx[d[o div 2]]) do
begin
y:=o div 2;
d[0]:=d[o];
d[o]:=d[y];
d[y]:=d[0];
o:=y;
end;
end;
procedure down(o:longint);
var
y:longint;
begin
while ((o*2<=p) and (yx[d[o*2]]>yx[d[o]])) or
((o*2+1<=p) and (yx[d[o*2+1]]>yx[d[o]])) do
begin
y:=o*2;
if (o*2+1<=p) and (yx[d[o*2+1]]>yx[d[o*2]]) then inc(y);
d[0]:=d[y];
d[y]:=d[o];
d[o]:=d[0];
o:=y;
end;
end;
procedure dg(o:longint);
var
i,l,m:longint;
begin
inc(cqy);
dfx[cqy]:=o;
yx[o]:=cqy;
l:=0;
while f[f[o,l],l]>0 do
begin
f[o,l+1]:=f[f[o,l],l];
inc(l);
end;
for i:=en[o-1]+1 to en[o] do
if fa[bj[i,2]]=0 then
begin
f[bj[i,2],0]:=o;
fa[bj[i,2]]:=o;
sd[bj[i,2]]:=sd[o]+1;
dg(bj[i,2]);
end;
if en[o-1]+1=en[o] then
begin
inc(p);
fd[o]:=true;
d[p]:=o;
up(p);
end;
end;
function bz(o:longint):longint;
var
i:longint;
begin
i:=20;
while i>=0 do
begin
if fz[f[o,i]] then o:=f[o,i];
dec(i);
end;
exit(o);
end;
begin
readln(n,t);
for i:=1 to n-1 do
begin
readln(bj[i*2-1,1],bj[i*2-1,2]);
bj[i*2,1]:=bj[i*2-1,2];
bj[i*2,2]:=bj[i*2-1,1];
inc(en[bj[i*2,1]]);
inc(en[bj[i*2,2]]);
end;
for i:=2 to n do
en[i]:=en[i-1]+en[i];
qsort(1,2*n-2);
fa[1]:=-1;
dg(1);
yx[-1]:=-1;
for i:=1 to t do
begin
readln(op,x);
if op=1 then
for l:=1 to x do
begin
fz[d[1]]:=true;
fd[d[1]]:=true;
ans:=d[1];
if (fz[fa[d[1]]]=false) and (fd[fa[d[1]]]=false) then
begin
fd[fa[d[1]]]:=true;
d[1]:=fa[d[1]];
down(1);
end
else
begin
d[1]:=-1;
down(1);
end;
end
else
begin
wz:=bz(x);
fz[wz]:=false;
writeln(sd[x]-sd[wz]);
fd[wz]:=true;
inc(p);
d[p]:=wz;
up(p);
end;
if op=1 then writeln(ans);
end;
end.