//最小堆算法
/*
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
struct node {
ll sum;
int i;
int j;
bool operator < (const node& x) const {
return this->sum > x.sum;
}
};
int a[N], b[N];
int n;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= n; ++i) cin >> b[i];
priority_queue<node> heap;
for (int i = 1; i <= n; ++i) {
heap.push({ a[1] + b[i], 1, i});
}
for (int k = 1; k <= n; ++k) {
node t = heap.top(); heap.pop();
ll sum = t.sum;
int i = t.i, j = t.j;
cout << sum << " ";
if(i + 1 <= n)
heap.push({ (ll)a[i + 1] + b[j], i + 1, j });
}
return 0;
}
*/
//无敌的暴力枚举
/*
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 1e5 + 10;
int arr1[N], arr2[N];
int n;
int main() {
priority_queue<int> result; // 最大堆,用来存储前 N 个最小的和(大顶堆)
cin >> n;
for (int i = 0; i < n; ++i) {
scanf("%d", &arr1[i]);
}
for (int i = 0; i < n; ++i) {
scanf("%d", &arr2[i]);
}
// 初始时,将 arr1[0] + arr2[i] 加入堆中
for (int i = 0; i < n; ++i) {
result.push(arr1[0] + arr2[i]);
}
// 然后,遍历 arr1 中的其它元素
for (int i = 1; i < n; ++i) {
for (int j = 0; j < n; ++j) {
int num = arr1[i] + arr2[j];
// 如果堆的大小超过 N,就删除堆顶元素(最大的和)
if (result.size() < n) {
result.push(num);
}
else if (num < result.top()) {
result.pop(); // 弹出堆顶元素
result.push(num); // 推入新的更小的和
}
else
break;
}
}
// 输出最小的 N 个和
vector<int> ans;
while (!result.empty()) {
ans.push_back(result.top());
result.pop();
}
// 由于堆顶是最大的,输出时需要反转
for (int i = ans.size() - 1; i >= 0; --i) {
cout << ans[i] << " ";
}
cout << endl;
return 0;
}
*/