洛谷 P1631 序列合併
阿新 • • 發佈:2018-12-23
題目:序列合併
首先,把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個佇列的下一個元素放入堆中。
時間複雜度:O (NlogN)。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define maxn 100000
#define read(x) scanf("%d",&x)
#define ll long long
struct Pair {
int x,y;
Pair(){}
Pair(int xx,int yy) {x=xx,y=yy;}
bool operator < (const Pair& oth) const {
return x>oth.x;
}
};
int n;
int a[maxn+ 5],b[maxn+5];
priority_queue<Pair> que;
int t[maxn+5];
int main() {
read(n);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) read(b[i]);
for(int i=1;i<=n;i++) {
que.push(Pair(a[1]+b[i],i));
t[i]=1;
}
for(int i=1;i<=n;i++) {
Pair h=que.top();que.pop();
if( t[h.y]!=n) {
t[h.y]++;
que.push(Pair(a[t[h.y]]+b[h.y],h.y));
}
printf("%d ",h.x);
}
return 0;
}