题意:有一个输入序列,每次操作要把b[i]插入到第a[i]个,在第a[i]个后面的要后移,问最后序列。
n<=200000
思路:顺序来只能用splay维护
考虑倒序,对于插入到第K个位置,在线段树二分第K个0的位置,类似于主席树
将其插入后将这个位置修改为已经有数
单点修改
1 var t:array[1..1000000]of longint; 2 a,b,c:array[1..300000]of longint; 3 n,i,k:longint; 4 5 procedure pushup(p:longint); 6 begin 7 t[p]:=t[p<<1]+t[p<<1+1]; 8 end; 9 10 function query(l,r,k,p:longint):longint; 11 var mid:longint; 12 begin 13 if l=r then exit(l); 14 mid:=(l+r)>>1; 15 if t[p<<1]>=k then exit(query(l,mid,k,p<<1)) 16 else exit(query(mid+1,r,k-t[p<<1],p<<1+1)); 17 pushup(p); 18 end; 19 20 procedure update(l,r,k,p:longint); 21 var mid:longint; 22 begin 23 if (l=k)and(r=k) then 24 begin 25 dec(t[p]); exit; 26 end; 27 mid:=(l+r)>>1; 28 if k<=mid then update(l,mid,k,p<<1) 29 else update(mid+1,r,k,p<<1+1); 30 pushup(p); 31 end; 32 33 procedure build(l,r,p:longint); 34 var mid:longint; 35 begin 36 if l=r then 37 begin 38 t[p]:=1; exit; 39 end; 40 mid:=(l+r)>>1; 41 build(l,mid,p<<1); 42 build(mid+1,r,p<<1+1); 43 pushup(p); 44 end; 45 46 begin 47 assign(input,'poj2828.in'); reset(input); 48 assign(output,'poj2828.out'); rewrite(output); 49 while not eof do 50 begin 51 readln(n); 52 if n=0 then break; 53 for i:=1 to n<<2 do t[i]:=0; 54 fillchar(c,sizeof(c),0); 55 for i:=1 to n do 56 begin 57 read(a[i],b[i]); 58 inc(a[i]); 59 end; 60 build(1,n,1); 61 for i:=n downto 1 do 62 begin 63 k:=query(1,n,a[i],1); 64 c[k]:=b[i]; 65 update(1,n,k,1); 66 end; 67 for i:=1 to n-1 do write(c[i],' '); 68 write(c[n]); 69 writeln; 70 end; 71 72 close(input); 73 close(output); 74 end.