洛谷 P1631 序列合并 题解
铺垫
二叉堆
概念:树形结构,父节点是所有节点中的最值
典型应用:
- 堆排序
- 优先队列
二叉堆支持:对最值的插入、删除、查询
本质:一棵满足“堆性质”的完全二叉树
根据完全二叉树的性质,采用层次序列的存储方法,用数组来保存二叉堆。有以下性质:
- i > 1 的节点,其父节点位于 i / 2
- 2 * i > n(节点总数),那么节点 i 没有孩子节点;如果2 * i + 1 > n,那么节点 i 不存在右孩子
- 如果节点 i 存在孩子节点,那么左孩子节点为 2 * i,右孩子节点为 2 * i + 1
堆的上浮
类似气泡上浮的过程
在最下一层最右边的叶子节点之后加入新元素。如果最下层已满,就新增一层
接着向上调整:如果这个节点的权值大于它的父节点的权值,那么交换。重复此过程,直到不满足或者到根为止
时间复杂度:\(O(log2 n)\)
代码
void push(int x)//加入大根堆
{
heap[++ len] = x;//加入最底层
int i = len;
while(i > 1 && heap[i / 2] < heap[i])//不断上浮
{
swap(heap[i / 2], heap[i]);
i = i / 2;//更新位置
}
}
堆的下沉
- 将根节点与对的最后一个元素交换
- 直接删掉最后一个元素
调整:在该结点的孩子节点中,找到一个最大的于该节点进行交换。重复直到到达底层
时间复杂度:\(O(log\ n)\)
代码
void pop()
{
//根节点与最后面的元素交换,删除它
heap[1] = heap[len --];
int i = 1;
while(2 * i <= len/*节点 i 存在孩子节点*/)//不断下沉
{
int son = 2 * i;
if(son < len && heap[son + 1] > heap[son])
{
son ++;
}
//下沉
if(heap[son] > heap[i])
{
swap(heap[son], heap[i]);
i = son;
}
else break;
}
}
题目思路(铺垫的多了一点)
最简单的:枚举出每一个和,求最小的 \(n\) 个
时间复杂度:\(O(n^2)\)
推测得分:50分(自己试)
观察图片:

我们可以建一个优先队列,存储 a[i] + b[1] 的值。
每次取出最小的 a[i] + b[j],输出,出队。
把 a[i] + b[j + 1] 入队
重复 \(n\) 次
这样保证就是最小的 \(n\) 个数
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
struct Node
{
int A, B, t; //需要知道取的是第几个数
}heap[N];
int len = 0;
void push(int x, int a, int b)
{
heap[++ len].t = x;
heap[len].A = a, heap[len].B = b;
int i = len;
while(i > 1 && heap[i / 2].t > heap[i].t)
{
swap(heap[i / 2], heap[i]);
i = i / 2;
}
}
void pop()
{
heap[1] = heap[len --];
int i = 1;
while(2 * i <= len)
{
int son = 2 * i;
if(son < len && heap[son + 1].t < heap[son].t)
{
son ++;
}
if(heap[son].t < heap[i].t)
{
swap(heap[son], heap[i]);
i = son;
}
else break;
}
}
int a[N], b[N];
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
for(int i = 1; i <= n; i ++)
{
cin >> b[i];
}
for(int i = 1; i <= n; i ++)
{
push(a[i] + b[1], i, 1);
}
for(int i = 1; i <= n; i ++)
{
cout << heap[1].t << ' ';
if(heap[1].B + 1 <= n/*判断是否越界*/) push(a[heap[1].A] + b[heap[1].B + 1], heap[1].A, heap[1].B + 1);
pop();
}
return 0;
}
hello, I'm yuzihang, if you need to copy this, please quote this url: https://www.cnblogs.com/yuzihang/articles/17395984.html

浙公网安备 33010602011771号