题意:给定一个容器,里面存放各种数值,规定三个操作,一个是在容器中增加一个数值,一个是在容器中删掉一个数值,一个是询问容器中比a大的数中第k大的数,将其输出。如果在删除过程中没有这个数,则输出"No Elment!",如果容器中没有比a大的第k个数,则输出"Not Find!".
这题因为是在线插入、删除和查找,所以就想到用线段树(树状数组也可以)。因为读入的数的范围是1到100000,所以就种一棵100000的线段树,每一个区间记录该区间有多少个数。然后插入和删除就是基本的操作啦。至于第三个操作,就先求出不大于a的数有多少个(设为x个),然后求第x+k大的数就是好啦。
代码:
var n,x,y,u,ans,i:longint; t:array[1..300000,1..3] of longint; procedure hehe(d,l,r:longint); var m:longint; begin t[d,1]:=l; t[d,2]:=r; t[d,3]:=0; if l=r then exit; m:=(l+r) div 2; hehe(d*2,l,m); hehe(d*2+1,m+1,r); end; procedure insert(d,x:longint); var m:longint; begin inc(t[d,3]); if (t[d,1]=x)and(t[d,2]=x) then exit; m:=(t[d,1]+t[d,2]) div 2; if x<=m then insert(d*2,x) else insert(d*2+1,x); end; function delete(d,x:longint):boolean; var m:longint; begin if (t[d,1]=t[d,2])and(t[d,1]=x) then begin if t[d,3]>0 then begin dec(t[d,3]); exit(true); end; exit(false); end; m:=(t[d,1]+t[d,2]) div 2; if x<=m then delete:=delete(d*2,x) else delete:=delete(d*2+1,x); if delete then dec(t[d,3]); end; function count(d,x:longint):longint; var m:longint; begin if t[d,1]=t[d,2] then exit(t[d,3]); m:=(t[d,1]+t[d,2]) div 2; if x<=m then count:=count(d*2,x) else count:=count(d*2+1,x)+t[d*2,3]; end; function find(d,x:longint):longint; var m:longint; begin if (t[d,3]=0)or(t[d,3]<x) then exit(0); if t[d,1]=t[d,2] then exit(t[d,1]); if x<=t[d*2,3] then find:=find(d*2,x) else find:=find(d*2+1,x-t[d*2,3]); end; begin while not eof do begin readln(n); hehe(1,0,100000); for i:=1 to n do begin read(x); if x=0 then begin readln(y); insert(1,y); end else if x=1 then begin readln(y); if delete(1,y)=false then writeln('No Elment!'); end else begin readln(x,y); u:=count(1,x); ans:=find(1,u+y); if ans=0 then writeln('Not Find!') else writeln(ans); end; end; end; end.