序列合併(luogu 1631)題解

2022-08-30 12:06:08 字數 3180 閱讀 2495

有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n^2個和,求這n^2個和中最小的n個。

32 6 6

1 4 8

3 6 7

這道題目其實是一道裸的最小堆的題目,而且它給出了ai<=a(i+1),bi<=b(i+1),我們連排序都可以不用排,我們建乙個堆為c,首先c中存放n個值,分別為a1+b1,a2+b1,...an+b1,然後我們將其建成乙個小根堆,每一次取堆頂元素並維護,然後插入ai+b(j+1)到堆中並維護,因此,我們需要乙個記錄型別來作為堆,該記錄型別有著三個值,分別儲存i,j和a[i]+b[j]的值,然後我們以a[i]+b[j]為關鍵字維護堆即可。

1

type rec=record

2jbh,data,ibh:longint;

3end

; 4

varn,i,j,n1,ii,jj:longint;

5 a,b:array[0..100010] of

longint;

6 c:array[0..100010] of

rec;

7procedure

sift(i,m:longint);

8var

k:longint;

9begin

10 c[0]:=c[i];

11 k:=i shl 1

; 12

while k<=m do

13begin

14if (kand(c[k].data1].data) then

15inc(k);

16if c[0].datathen

17begin

18 c[i]:=c[k];

19 i:=k;

20 k:=i shl 1

; 21

end22

else

23 k:=m+1

; 24

end;

25 c[i]:=c[0

];

26end

; 27

procedure

insert(k,ii,jj:longint);

28var

i:longint;

29y:rec;

30begin

31inc(n1);

32 c[n1].data:=k;

33 c[n1].ibh:=ii;

34 c[n1].jbh:=jj;

35 i:=n1;

36while (i shr 1>0)and(c[i shr 1].data>k) do

37begin

38 y:=c[i];

39 c[i]:=c[i shr 1

];

40 c[i shr 1]:=y;

41 i:=i shr 1

; 42

end;

43end

; 44

procedure

heapsort;

45var

j:longint;

46y:rec;

47begin

48for j:=n shr 1

downto1do

49sift(j,n);

50for j:=n downto2do

51begin

52 y:=c[1

];

53 c[1]:=c[j];

54 c[j]:=y;

55 sift(1,j-1

);

56end

; 57

end;

58function

deletemin:longint;

59var

i,pos:longint;

60y:rec;

61begin

62 i:=1

; 63 deletemin:=c[1

].data;

64 c[1]:=c[n1];

65dec(n1);

66while i shl 1

<=n1 do

67begin

68 pos:=i shl 1

; 69

if (posand(c[pos+1].datathen

70inc(pos);

71if c[i].data>c[pos].data then

72begin

73 y:=c[i];

74 c[i]:=c[pos];

75 c[pos]:=y;

76 i:=pos;

77end

78else

79break;

80end

; 81

end;

82begin

83readln(n);

84for i:=1

to n do

85read(a[i]);

86for i:=1

to n do

87read(b[i]);

88for i:=1

to n do

89begin

90 c[i].data:=a[i]+b[1

];

91 c[i].jbh:=1

; 92 c[i].ibh:=i;

93end

; 94

heapsort;

95 n1:=n;

96for i:=1

to n do

97begin

98 ii:=c[1

].ibh;

99 jj:=c[1

].jbh;

100 write(deletemin,'

');

101inc(jj);

102 insert(a[ii]+b[jj],ii,jj);

103end

; 104

end.

Luogu 1631(優先佇列)

傳送門 題意 有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到 題解 先排序得到兩個遞增的數列a和b,然後用小根堆維護a b,每次取隊首,如果這次取出的是a i b j 則往佇列中 插入a i b j 1 所以需要另開乙個陣列p i 來記錄每乙個a i 應該匹配的b。正確性顯然 取前k...

P1631 序列合併

做法 將 a 和 b 都從小到大排一遍序。然後組成這樣乙個矩陣 a1 b1 a1 b2 a1 b3 a1 bn a2 b1 a2 b2 a2 b3 a2 bn a3 b1 an b1 an b2 an b3 an bn 正確性 我們先把每行的頭扔進堆裡,每行的頭是每行中的最小值,所以這樣我們能在堆裡...

洛谷1631 序列合併

題目描述 有兩個長度都是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 的資料中,滿...