Long long ago,我曾经想过要写堆排(话说已经是刚开始写二分那个博客的时候了),后来好久没写,现在总算想到要写了……
好了,进入正题。
我以前曾经自己打过一个课件,现在打算放在优快云下载那里,就当是放基础知识了,现在写写一道题的题解……
PPT网址如下(下载者先交1积分……):http://download.youkuaiyun.com/detail/u014120397/9472391
题目:codevs1245
链接:http://codevs.cn/problem/1245/
K路归并,初始化的时候把a,b数组排个序,然后把a[1]+b[1],a[2]+b[1]……a[n]+b[1]放入小根堆里面,然后每出一次堆,比如说把a[i]+b[1]出堆了,那么就把a[i]+b[2]入堆,如此操作执行n次就可以了。时间复杂度O(n log n)
代码:
type arr=array[1..100000]of longint;
ijk=record
sum,b:longint;
end;
var heap:array[0..1000000]of ijk;
buf:ijk;
a,b:arr;
n,i,length:longint;
procedure qs(l,r:longint;var a:arr);
var i,j:longint;
x,y:longint;
begin
i:=l;
j:=r;
x:=a[(l+r) shr 1];
repeat
while a[i]<x do
inc(i);
while a[j]>x do
dec(j);
if i<=j then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
dec(j);
end;
until i>j;
if l<j then qs(l,j,a);
if i<r then qs(i,r,a);
end;
procedure minheapify(x:longint);
var min,l,r:longint;
begin
l:=x shl 1;
r:=l+1;
min:=x;
if (l<=length)and(heap[l].sum<heap[min].sum) then
min:=l;
if (r<=length)and(heap[r].sum<heap[min].sum) then
min:=r;
if min<>x then
begin
heap[0]:=heap[x];
heap[x]:=heap[min];
heap[min]:=heap[0];
minheapify(min);
end;
end;
procedure sinkup(i:longint);
var parent,tmp:longint;
begin
parent:=i shr 1;
if (parent<>0)and(heap[parent].sum>heap[i].sum) then
begin
heap[0]:=heap[i];
heap[i]:=heap[parent];
heap[parent]:=heap[0];
if parent>1 then sinkup(parent);
end;
end;
function popheap:ijk;
var min:ijk;
begin
if length=0 then exit;
min:=heap[1];
heap[1]:=heap[length];
dec(length);
minheapify(1);
exit(min);
end;
procedure pushheap(buf:ijk);
begin
inc(length);
heap[length]:=buf;
if length>1 then
sinkup(length);
end;
begin
readln(n);
for i:=1 to n do
read(a[i]);
for i:=1 to n do
read(b[i]);
qs(1,n,a);
qs(1,n,b);
for i:=1 to n do
begin
buf.sum:=a[i]+b[1];
buf.b:=1;
pushheap(buf);
end;
for i:=1 to n do
begin
buf:=popheap;
if i<>n then write(buf.sum,' ')else writeln(buf.sum);
if buf.b<=n then
begin
buf.sum:=buf.sum-b[buf.b]+b[buf.b+1];
inc(buf.b);
pushheap(buf);
end;
end;
end.