有序表的最小和

Description

给出两个长度为n的有序表A和B,在A和B中各任取一个元素,可以得到n^2个和,求这些和中最小的n个

Input

第一行包含一个整数n(n≤400000n≤400000)

第二行与第三行分别有n个整数,分别代表有序表A和B,整数之间由一个空格隔开,大小在长整数范围之内,保证有序表的数据单调递增。

Output

输出共n行,每行一个整数,第i行为第i小的和,数据保证在长整数范围之内

Samples

Input

1
2
3
3
1 2 5
2 4 7

Output

1
2
3
3
4
5

AC CODE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int INF = 0x3f3f3f3f ;
const int N = 4e5 + 5;
int a[N],b[N];
struct node {
int w;
int i,j;
friend bool operator< (node a,node b) {
return a.w > b.w;
}
};
priority_queue<node> q;
int main(){
int n,x,y;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++) {
scanf("%d",&b[i]);
q.push({a[i]+b[1],i,1});
}
for(int i=1;i<=n;i++) {
node tmp = q.top();q.pop();
printf("%d\n",tmp.w);
x = tmp.i,y = tmp.j;
tmp.w = a[x]+b[y+1];
tmp.j++;
q.push(tmp);
}
return 0;
}

解析:

同样是很有趣的一道题。

假设有a,b两个数组,首先我们知道最小的和必然是a[1] + b[1]

那么第二小的是什么呢?

可能是a[1] + b[2] 也可能是 a[2] + b[1] 做成表格是这样的:

有序表的最小和.png

假设每个数组有四项,第一小的就要从第一列找到最小的一个输出,然后被选中的向后推移一项继续比较每一行被选中的。

最小的只能从这n个中产生。

模拟一下过程就是code中那样。

值得一提的是优先队列制定排序的规则,这里用的是在结构体中重载运算符,之后会专门做一篇博客解释这个。