序列合併
問題描述
有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n^2個和,求這n^2個和中最小的n個(n<=100000)。
分析
a[i]與b[j]相加後,下面相加的一定是a[i+1]+b[j]或a[i]+b[j+1],一開始我們把b[1]與a中所有元素相加放入乙個小根堆裡,輸出min,然後把堆頂與b[2]相加,維護堆後輸出……,為避免重複相加,需要開乙個陣列記錄堆裡第i個元素是與b中第幾個元素相加的結果,在下次相加是直接加b中下乙個。
時間複雜度
o(n logn)
**
const
maxn=100000;
type
arr=array[0..maxn] of longint;
vara,b,c,p:arr;
i,j,n,m:longint;
procedure down(i:longint);
vardone:boolean;
begin
done:=false;
repeat
i:=2*i;
if (i+1<=n) and (p[i]>p[i+1]) then inc(i);
if p[i div 2]>p[i] then
begin
c[0]:=c[i];
c[i]:=c[i div 2];
c[i div 2]:=c[0];
p[0]:=p[i];
p[i]:=p[i div 2];
p[i div 2]:=p[0];
endelse done:=true;
until (2*i>n) or done;
end;
begin
readln(n);
for i:=1 to n do
read(a[i]);
for i:=1 to n do
read(b[i]);
for i:=1 to n do
begin
c[i]:=1;
p[i]:=a[i]+b[1];
end;
for i:=n div 2 downto 1 do
down(i);
for i:=1 to n do
begin
write(p[1],' ');
p[1]:=p[1]-b[c[1]]+b[c[1]+1];
inc(c[1]);
down(1);
end;
end.
洛谷 P1631 序列合併
題目描述 有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個。輸入輸出格式 輸入格式 第一行乙個正整數n 第二行n個整數ai,滿足ai ai 1且ai 10 9 第三行n個整數bi,滿足bi bi 1且bi 10 9.資料規模 對於50 的資料中,滿...
洛谷 P1631 序列合併
有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個。第一行乙個正整數n 第二行n個整數ai,滿足ai ai 1且ai 10 9 第三行n個整數bi,滿足bi bi 1且bi 10 9.輸出僅一行,包含n個整數,從小到大輸出這n個最小的和,相鄰數字之間...
洛谷p1631 序列合併
有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到 n 2n2 個和,求這 n 2n2 個和中最小的n個。輸入格式 第一行乙個正整數n 第二行n個整數 a iai 滿足 a i le a ai ai 1 且 a i le 10 9ai 109 第三行n個整數 b ibi 滿足 b i l...