ORDERSET - Order statistic set
Tác giả: RR
Ngôn ngữ: Pascal
{$R+,Q+}
const finp='';
fout='';
MaxQ=200000;
MaxD=4*MaxQ;
Var A:Array[1..MaxQ] of Longint;
Var ID:Array[1..MaxQ] of Longint;
Var Oder:Array[1..MaxQ] of Char;
Var Q,N,U:Longint;
Var F:Array[1..MaxD] of Longint;
(***************************)
procedure OpenFile; inline;
begin
assign(input,finp);reset(input);
assign(output,fout);rewrite(output);
end;
(****************************)
procedure CloseFile; inline;
Begin
Close(input);
Close(output);
End;
(**************************************)
procedure QS(l,r:longint); inline;
var i,j:longint;
tg,k:longint;
begin
if l>=r then exit;
k:=A[l+random(r-l+1)];
i:=l;
j:=r;
repeat
while (A[i]<K) do inc(i);
while (A[j]>K) do dec(j);
if i<=j then
Begin
Tg:=A[i];A[i]:=A[j];A[j]:=tg;
Inc(i);
Dec(j);
End;
until i>j;
QS(L,j);
QS(i,R);
end;
(*******************************)
Procedure Init; inline;
Var j,i:Longint;
Begin
j:=1;
For i:=2 to Q do
If A[i]<>A[j] Then
Begin
Inc(j);
A[j]:=A[i];
End;
N:=j;
End;
(*******************************)
procedure Enter; inline;
Var i:Longint;
Begin
Readln(Q);
For i:=1 to Q do
Begin
Readln(Oder[i],A[i]);
ID[i]:=A[i];
End;
QS(1,Q);
Init;
End;
(*******************************)
Procedure Inc_Seq(L,R,K:Longint); inline;
Var Mid,Con:Longint;
Begin
If (A[R]<U)Or(A[L]>U) Then Exit;
If (L=R)Then
Begin
F[K]:=1; Exit;
End;
Mid:=(L+R) Shr 1;
Con:=K Shl 1;
Inc_Seq(L,Mid,Con);
Inc_Seq(Mid+1,R,Con+1);
F[K]:=F[Con]+F[Con+1];
End;
(*******************************)
Procedure Dec_Seq(L,R,K:Longint); inline;
Var Mid,Con:Longint;
Begin
If (A[R]<U)Or(A[L]>U) Then Exit;
If (L=R)Then
Begin
F[K]:=0; Exit;
End;
Mid:=(L+R)shr 1;
Con:=K Shl 1;
Dec_Seq(L,Mid,Con);
Dec_Seq(Mid+1,R,Con+1);
F[K]:=F[Con]+F[Con+1];
End;
(*******************************)
Function Find(L,R,K:Longint):Longint; inline;
Var Mid:Longint;
Con:Longint;
Begin
If L=R Then Exit(L);
Mid:=(L+R) shr 1;
Con:=K Shl 1;
If F[Con]>=U Then Find:=Find(L,Mid,Con)
Else
Begin
U:=U-F[Con];
Find:=Find(Mid+1,R,Con+1);
End;
End;
(*******************************)
Function Get_Seq(L,R,K:Longint):Longint; inline;
Var Mid:Longint;
Con:Longint;
Begin
Get_Seq:=0;
If A[L]>=U Then Exit;
If A[R]<U Then
Begin
Get_Seq:=F[K];
Exit;
End;
Mid:=(L+R) shr 1;
Con:=K Shl 1;
Get_Seq:=Get_Seq(L,Mid,Con)+Get_Seq(Mid+1,R,Con+1);
End;
(*******************************)
procedure Solve;
Var i:Longint;
Begin
For i:=1 to Q do
Begin
U:=ID[i];
If Oder[i]='I' Then Inc_Seq(1,N,1)
Else
If Oder[i]='D' Then Dec_Seq(1,N,1)
Else
If Oder[i]='K' Then
Begin
If U>F[1] Then Writeln('invalid')
Else Writeln(A[Find(1,N,1)]);
End
Else Writeln(Get_Seq(1,N,1));
End;
End;
(*******************************)
Begin
OpenFile;
Enter;
Solve;
CloseFile;
End.