P1631 序列合併 思維 堆優化

2022-06-12 21:15:13 字數 919 閱讀 5958

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

\[a_i \leq a_,a_i \leq 10^9\\

b_i \leq b_,b_i\leq 10^9\\

n\leq 10^5

\]注意到問題可以轉化為在乙個\(n \times n\)的矩陣中選擇\(n\)個最小的元素

注意到這個矩陣的特點,從左到右以及從上到下都是遞增的,因此每次選擇實際上都是只在有限個數中選取

維護一列數,若其中某個數是最小的則彈出,加入這個數的下一列數

顯然維護的第一列數是可以是第一列

因此可以用堆來維護

**用用負數push,可以不用寫比較函式

時間複雜度\(o(nlogn)\)

#includeusing namespace std;

typedef unsigned long long ull;

typedef long long ll;

ull readull()

while(ch >= '0' && ch <= '9')

return f * x;

}int readint()

while(ch >= '0' && ch <= '9')

return f * x;

}#define pii pair#define fi first

#define se second

const int maxn = 1e5 + 5;

int a[maxn];

int b[maxn];

int cur[maxn];

priority_queueq;

int main()

}

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 正確性 我們先把每行的頭扔進堆裡,每行的頭是每行中的最小值,所以這樣我們能在堆裡...

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 的資料中,滿足1 n 1000 對於...

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 10 9 第三行n個整數 b ibi 滿足 b i ...