poj 1442 Black Box

来源:互联网 发布:mac os 10.8无法升级 编辑:程序博客网 时间:2024/05/10 08:22

http://poj.org/problem?id=1442

题目又臭又长就不贴了,给两串数a[i],u[i]长度分别为M,N(我读入的时候是N,M。习惯了。。。)。对于每个u[i],输出a数组前u[i]个中从小到大的第i个数。

//================================================================================================

其实这道题可以用大根堆+小根堆做的,但是为了练手就用Treap硬搞掉了。。。

大根堆+小根堆的做法就是保证大根堆的大小为i,每次加入新数先入大根堆,弹出堆顶的数,把这个数放入小根堆,询问的时候就是大根堆堆顶的数,处理下一个u[i+1]的时候从小根堆弹出堆顶的数加入大根堆。

就是弹来弹去的。。。YY下就出来了。。。不过我还没有实现,如果有错求指教、、

Treap这个就不用说了吧,都是Treap的基本操作:加入一个数。询问k大的数。

一开始在询问k大值调用函数find的时候当过程用了。。。值没有传上去。。。

竟然浪费了时间去调这种错误、、、不可饶恕啊!!!

 

ACCODE

 

program pku_1442;
const maxn=99999999;
var val,a,fix,sum,left,right:array[0..30000] of longint;
   root,n,m,i,x,now,num,z,tot:longint;
//============================================================================
procedure right_rotate(var k:longint);
var t:longint;
begin
  t:=left[k];
  sum[k]:=sum[right[t]]+sum[right[k]]+1;
  left[k]:=right[t];
  right[t]:=k; k:=t;
  sum[k]:=sum[left[k]]+sum[right[k]]+1;
end;
//============================================================================
procedure left_rotate(var k:longint);
var t:longint;
begin
  t:=right[k];
  right[k]:=left[t];
  sum[k]:=sum[left[t]]+sum[left[k]]+1;
  left[t]:=k; k:=t;
  sum[k]:=sum[left[k]]+sum[right[k]]+1;
end;
//============================================================================
procedure ins(var k:longint);
begin
  if k=0 then
  begin
    inc(tot);k:=tot;
    a[k]:=z;sum[k]:=1;
   fix[k]:=random(maxn);
    exit;
  end;
  if z<a[k] then
  begin
   ins(left[k]); sum[k]:=sum[left[k]]+sum[right[k]]+1;
    iffix[left[k]]>fix[k] then right_rotate(k);
  end else
  begin
   ins(right[k]); sum[k]:=sum[left[k]]+sum[right[k]]+1;
    iffix[right[k]]>fix[k] then left_rotate(k);
  end;
end;
//============================================================================
function find(k:longint):longint;
begin
  if sum[left[k]]=num-1 then exit(a[k]) else
  if sum[left[k]]>=num thenexit(find(left[k]))else   //一开始直接写了find(left[k])。。。
  begin
   num:=num-sum[left[k]]-1;
   exit(find(right[k]));   //这里也是。。编程手感实在不行啊。。。。。。。
  end;
end;
//============================================================================
begin
  randomize;
  readln(n,m);
  for i:=1 to n do read(val[i]);
  now:=0; root:=0;
  for i:=1 to m do
  begin read(x);
    whilenow<x do
    begin
     inc(now); z:=val[now];
     ins(root);
    end;num:=i;
   writeln(find(root));
  end;
end.

0 0