【Data Structures】寻找第k大

对于BST,无压力的可以,所以无需赘言,请见代码。

  1: Program Bst_KthFind(input,output);
  2:   type point=^node;
  3:        node=record
  4:          data,leftsum,rightsum:longint;
  5:          left,right:point;
  6:   end;
  7:   var ch:char;i,n,q:longint;flag:boolean;root:point;
  8:   procedure insert(var p:point;x:longint);
  9:     begin
 10:       if p=nil then 
 11:         begin
 12:           new(p);p^.data:=x;p^.right:=nil;p^.left:=nil;p^.rightsum:=0;p^.leftsum:=0;
 13:           if flag then  begin root:=p;flag:=false;end;
 14:         end else
 15:       if x>=p^.data then 
 16:         begin
 17:           insert(p^.right,x);
 18:           inc(p^.rightsum);
 19:         end
 20:       else begin
 21:              insert(p^.left,x);
 22:              inc(p^.leftsum);
 23:            end;
 24:     end;
 25:   Function Find(p:point;x:longint):longint;
 26:     begin
 27:       if p^.leftsum=x-1 then exit(p^.data);
 28:       if p^.leftsum>x-1 then exit(Find(p^.left,x));
 29:       if p^.leftsum<x-1 then exit(Find(p^.right,x-p^.leftsum-1));
 30:     end; 
 31:   begin
 32:     readln(n);root:=nil;flag:=true;
 33:     for i:=1 to n do 
 34:       begin
 35:         read(ch);readln(q);
 36:         case ch of 
 37:           'i' : insert(root,q);
 38:           'f' : writeln(Find(root,q));
 39:         end;
 40:       end;
 41:   end.

另一种思路,是利用树状数组。但这个东西局限性很大,因为数组C[i]表示的是比i这个数小的数的个数,也就是说出现了Maxlongint大小的数字就无法处理了。大致思路如下

  1: Program Problem1(input,output);
  2:   var c:array[0..300000]of longint;
  3:       n,i,tot,q:longint;ch:char;
  4:   Function lowbit(x:longint):Longint;
  5:     begin exit(x and -x);end;
  6:   procedure add(p:longint);
  7:     begin
  8:       while p<=300000 do
  9:         begin
 10:           inc(c[p]);
 11:           inc(p,lowbit(p));
 12:         end;
 13:     end;
 14:   function find_kth(x:longint):longint;
 15:     var i,ans,cnt:longint;
 16:     begin
 17:       ans:=0;cnt:=0;
 18:       for i:=19 downto 0 do
 19:         begin
 20:           inc(ans,1<<i);
 21:           if(ans>300000)or(cnt+c[ans]>=x)then dec(ans,1<<i)
 22:           else inc(cnt,c[ans]);
 23:         end;
 24:       exit(ans+1);
 25:     end;
 26:   begin
 27:     readln(n);
 28:     for i:=1 to n do
 29:       begin
 30:         read(ch);readln(q);
 31:         case ch of
 32:           'i' : begin add(q);inc(tot);end;
 33:           'f' : writeln(find_kth(q));
 34:         end;
 35:       end;
 36:   end.
原文地址:https://www.cnblogs.com/Loongint/p/2215527.html