首先,把A和B两个序列分别从小到大排序,变成两个有序队列。这样,从A和B中各任取一个数相加得到N2个和,可以把这些和看成形成了n个有序表/队列:
A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N]
A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N]
……
A[N]+B[1] <= A[N]+B[2] <= … <= A[N]+B[N]
接下来,就相当于要将这N个有序队列进行合并排序:
首先,将这N个队列中的第一个元素放入一个堆中;
然后;每次取出堆中的最小值。若这个最小值来自于第k个队列,那么,就将第k个队列的下一个元素放入堆中。
假设我们当前取出的是a[i]+b[j],那么我们下一次取的就是a[i]+b[j+1]或a[i+1]+b[j]。我们先把b序列中所有数与a[1]的和放入优先队列,这样就满足了a[i]+b[j+1]的情况。所以重点就是处理a[i+1]+b[j],每次把取出b[j]对应的取到a数组中的位置往后移一个加入优先队列即可。
const int N=1e5+10;
struct Node
{
int i,j;
int sum;
bool operator>(const Node &W) const
{
return sum > W.sum;
}
};
int a[N],b[N];
int n;
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
priority_queue<Node,vector<Node>,greater<Node>> heap;
for(int i=0;i<n;i++)
{
cin>>b[i];
heap.push({i,0,a[i]+b[0]});
}
for(int i=0;i<n;i++)
{
Node t=heap.top();
heap.pop();
cout<<t.sum<<' ';
heap.push({t.i,t.j+1,a[t.i]+b[t.j+1]});
}
cout<<endl;
//system("pause");
return 0;
}