洛谷P1631 序列合併

2021-07-26 09:22:59 字數 1354 閱讀 1083

序列合併

問題描述

有兩個長度都是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...