这题做了大半个晚上,而且还是看了好久题解才做出来的,看来自己还是太水了。
首先大概思路就是从后往前处理,根据每一个人后面的人来推出这个人所处的位置,而重点就在于如何推出每个人的位置。首先建一颗线段树,节点储存的是该区间还有多少个空格。而对于每一个人所插入的位置x则表示该时刻这个人前面应该还剩x个空格(自己想为什么),若左节点的空格数大于x则搜索左节点,否则搜索右节点。注意在搜索右节点是要先把x减去左节点的空格数。
下面附程序:
var n,i:longint; t:array[1..600000,1..3] of longint; a,x,y:array[1..200000] of longint; procedure hehe(d,l,r:longint); var m:longint; begin t[d,1]:=l; t[d,2]:=r; t[d,3]:=r-l+1; if l=r then exit; m:=(l+r) div 2; hehe(d*2,l,m); hehe(d*2+1,m+1,r); end; function work(d,x:longint):longint; begin dec(t[d,3]); if t[d,1]=t[d,2] then exit(t[d,1]); if t[d*2,3]>x then work:=work(d*2,x) else work:=work(d*2+1,x-t[d*2,3]); end; begin while not eof do begin readln(n); hehe(1,1,n); for i:=1 to n do readln(x[i],y[i]); a[work(1,x[n])]:=y[n]; for i:=n-1 downto 1 do a[work(1,x[i])]:=y[i]; for i:=1 to n do write(a[i],' '); writeln; end; end.