CF754D Fedor and coupons(堆)

题目

我们所有的角色都有某些习惯。Fedor 也一样。他在邻近的超市享受购物。

超市的不同货物有不同的整数 ID。对于每个整数也有一个产品的 ID 和这个整数相同。Fedor 有 n n n 张折扣券,它们中的第 i i i 张可以用于 ID 范围介于 [ l i , r i ] [l_i, r_i] [li,ri] 的产品。今天 Fedor 想要携带恰好 k k k 张折扣券。

Fedor 想要选择 k k k 张折扣券,使得所有的折扣券都可以用于尽可能多的产品数目 x x x (为了最好的理解,参见样例)。Fedor 同时也想节省时间,所以他请求你为他选择折扣券。请帮帮 Fedor!

简要题意: 从 n n n个区间中选出恰好 k k k个, 最大化公共部分的长度.

CF754D Fedor and coupons

题解

  • 将左端点从小到大排序,然后用小根堆堆维护右端点(堆的大小为k)
  • 为什么要用小根堆呢:因为我们要让区间长度尽可能的长,所以我们要每次弹出最小值qwq

c o d e code code

#include <bits/stdc++.h> 
using namespace std; 
const int maxn = 300000 + 100; 

template <class T> 
inline void read(T &s) {
	s = 0; 
	T w = 1, ch = getchar(); 
	while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
	while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
	s *= w; 
}

int n, k; 
struct node { 
	int l, r, id; 
	bool operator <(const node &A) const {
		return l < A.l; 
	}
}; 
node s[maxn]; 
priority_queue<int> p; 

int main() {
	read(n), read(k); 
	for (int i = 1; i <= n; ++i) {
		read(s[i].l), read(s[i].r); 
		s[i].id = i; 
	}

	sort(s + 1, s + n + 1); 

	int len = 0, L = 0, R = 0; 
	for (int i = 1; i <= n; ++i) {
		p.push(-s[i].r); 
		if (p.size() > k) p.pop(); 
		if (p.size() == k) {
			int now = (-p.top()) - s[i].l + 1; 
			if (now > len) {
				len = now; 
				L = s[i].l; 
				R = (-p.top()); 
			}
		}
	}

	printf("%d\n", len); 
	if (!len) {
		for (int i = 1; i <= k; ++i) 
			printf("%d ", i); 
	} 
	else {
		// printf("L = %d R = %d\n", L, R); 
		for (int i = 1, j = 1; i <= n && j <= k; ++i) {
			if (s[i].l <= L && s[i].r >= R) {
				printf("%d ", s[i].id), ++j; 
			}
		}
	}
	return 0; 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值