【洛谷P1631】序列合并【堆】
题目大意:
题目链接:https://www.luogu.org/problemnew/show/P1631
有两个长度都是的序列和,在和中各取一个数相加可以得到个和,求这个和中最小的个。
题外话:
我的正确率是真的低qwq
思路:
由于题目中说都是单调递增的。所以就可以不考虑排序。
单调递增同时特满足了
所以我们每次只要维护个数的最小值就可以了(分别是,其中表示所维护完的数组指针)
求最小值可以考虑维护一个小根堆。每一个元素维护一个三元组,表示这个的值。
如果是堆里的最小值,那么就输出,弹出,并插入。
做次上述方法即可。
时间复杂度
代码:
#include <queue>
#include <cstdio>
#define mp make_pair
using namespace std;
const int N=100010;
int n,a[N],b[N];
priority_queue<pair<int,pair<int,int> > > q; //pair套pair最为致命(三元组)
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
scanf("%d",&b[i]);
for (int i=1;i<=n;i++)
q.push(mp(-a[i]-b[1],mp(i,1))); //插入初始值
for (int i=1;i<=n;i++)
{
printf("%d ",-q.top().first);
int x=q.top().second.first,y=q.top().second.second;
q.pop();
q.push(mp(-a[x]-b[y+1],mp(x,y+1)));
}
return 0;
}