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.

posted @ 2009-01-04 12:23  jesonpeng  阅读(295)  评论(0编辑  收藏  举报