堆的学习 + 刷题日记

目录

学习笔记(模板)

1. 手动建大顶堆

2. 手动堆排序(大顶堆)

3. 万能的STL大法

4. 快速优先队列比大小(priority_queue重载运算符)

刷题笔记

一本通1369:合并果子(fruit) && 洛谷 P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G


学习笔记(模板)

1. 手动建大顶堆

以下是函数模板。

void push(int x) {
	int next, now = ++ heapSize;
	heap[heapSize] = x;
	while(now > 1) {
		next = now >> 1; // next = now / 2;
		if(heap[now] > heap[next])
			swap(heap[now], heap[next]);
		else break;
		now = next;
	}
}

小顶堆就是把 ">" 改成 "<",其他一模一样。。。

2. 手动堆排序(大顶堆)

int pop() {
	int ans = heap[1];
	heap[1] = heap[heapSize --];
	int now = 1;
	while(now * 2 <= heapSize) {
		int next = now * 2;
		if(next < heapSize && heap[next] < heap[next + 1])
			next ++;
		if(heap[now] < heap[next]) swap(heap[now], heap[next]);
		else break;
		now = next;
	}
	return ans;
}

不给出小顶堆了(就是把 "heap[next] < heap[next + 1]" 反过来),时间复杂度 O(logn * n)。

3. 万能的STL大法

push 是 建堆,pop 是堆排序。

// greater<int>() 小顶堆 
// less<int>() 大顶堆 
void push(int x) {
	heap[++ heapSize] = x;
	push_heap(heap + 1, heap + 1 + heapSize, greater<int>());
}

int pop() {
	pop_heap(heap + 1, heap + 1 + heapSize, greater<int>());
	return heap[heapSize --];
}

大大节省了码量。。。

4. 快速优先队列比大小(priority_queue重载运算符)

bool operator < (node a, node b) {
	return a.n > b.n;
}

刷题笔记

一本通1369:合并果子(fruit) && 洛谷 P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G

题目链接:一本通 / 洛谷

一道小顶堆题,堪称模板。。。

#include <bits/stdc++.h>
#define N 30010
using namespace std;

int n, a[N], heapSize;
long long ans;

void push(int x) {
	a[++ heapSize] = x;
	push_heap(a + 1, a + 1 + heapSize, greater<int>());
}

int pop() {
	pop_heap(a + 1, a + 1 + heapSize, greater<int>());
	return a[heapSize --];
}

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		int tmp;
		scanf("%d", &tmp);
		push(tmp);
	}
	while(heapSize > 1) {
		int sum = pop() + pop();
		ans += sum;
		push(sum);
	}
	cout << ans << endl;
	return 0;
}

一本通1371:看病

十分水,一遍过。。。

#include <bits/stdc++.h>
using namespace std;

struct node {
	string s;
	int c;
};
priority_queue<node> q;

bool operator < (node a, node b) {
	return a.c < b.c;
}

int t;

int main() {
	scanf("%d", &t);
	while(t --) {
		string op;
		cin >> op;
		if(op == "pop") {
			if(q.empty()) cout << "none\n";
			else {
				cout << q.top().s << ' ' << q.top().c << endl;
				q.pop();
			}
		}
		else {
			node tmp;
			cin >> tmp.s >> tmp.c;
			q.push(tmp);
		}
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值