【POJ2828】Buy Tickets(线段树)

题意:有一个输入序列,每次操作要把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.

 

posted on 2016-12-30 20:51  myx12345  阅读(177)  评论(0编辑  收藏  举报

导航