PKU 2828 线段树
http://hi.baidu.com/raulliubo/blog/item/801aca168f3fdd1c972b43f8.html
这个题琢磨了一阵子。。。发现由于最后一个人的位置肯定是固定的,所以我们可以从后往前推,即从最后一个插队的人开始推。设一个长度为n的值全为1的序列。一个人的插入位置若为pos,则它在序列中的最终位置就是pos+1(因为他是站在pos后面)。
想明白这个应该就很好做了。
my ugly code:
var
len, right, left : array[0 .. 800000] of longint;
v, p, ans : array[1 .. 200000] of longint;
n, i : longint;
procedure buildtree(now, l, r : longint);
begin
if l = r then begin
left[now] := l;
right[now] := r;
len[now] := 1;
exit;
end;
left[now] := l;
right[now] := r;
len[now] := r - l + 1;
buildtree(now * 2, left[now], (left[now] + right[now]) shr 1);
buildtree(now * 2 + 1, (left[now] + right[now]) shr 1 + 1, right[now]);
end;
procedure insert(now, value, pos : longint);
begin
dec(len[now]);
if left[now] = right[now] then begin
ans[left[now]] := value;
exit;
end;
if len[now * 2] > pos then
insert(now * 2, value, pos)
else
insert(now * 2 + 1, value, pos - len[now * 2]);
end;
begin
while not eof do begin
readln(n);
buildtree(1, 1, n);
for i := 1 to n do
readln(p[i], v[i]);
for i := n downto 1 do
insert(1, v[i], p[i]);
for i := 1 to n-1 do write(ans[i],' ');
writeln(ans[n]);
end;
end.