区间交集最值

D. Fedor and coupons

题意

All our characters have hobbies. The same is true for Fedor. He enjoys shopping in the neighboring supermarket.

The goods in the supermarket have unique integer ids. Also, for every integer there is a product with id equal to this integer. Fedor has n discount coupons, the i-th of them can be used with products with ids ranging from li to ri, inclusive. Today Fedor wants to take exactly k coupons with him.

Fedor wants to choose the k coupons in such a way that the number of such products x that all coupons can be used with this product x is as large as possible (for better understanding, see examples). Fedor wants to save his time as well, so he asks you to choose coupons for him. Help Fedor!

Input

The first line contains two integers n n n and k ( 1   ≤   k   ≤   n   ≤   3 ⋅ 1 0 5 ) {k (1 ≤ k ≤ n ≤ 3·10^5) } k(1 kn 3105) — the number of coupons Fedor has, and the number of coupons he wants to choose.

Each of the next n n n lines contains two integers l i l_i li and r i (   − 1 0 9   ≤   l i   ≤   r i   ≤   1 0 9 ) {r_i ( -10^9 ≤ l_i ≤ r_i ≤ 10^9) } ri(109liri 109)— the description of the i − t h i-th ith coupon. The coupons can be equal.

Output

In the first line print single integer — the maximum number of products with which all the chosen coupons can be used. The products with which at least one coupon cannot be used shouldn’t be counted.

In the second line print k distinct integers p 1 ,   p 2 ,   . . . ,   p k ( 1   ≤   p i   ≤   n ) p1, p2, ..., pk (1 ≤ pi ≤ n) p1,p2, ...,pk(1 pin) — the ids of the coupons which Fedor should choose.

If there are multiple answers, print any of them.

Examples

样例 #1

4 2
1 100
40 70
120 130
125 180
31
1 2 

样例 #2

3 2
1 12
15 20
25 30
0
1 2 

样例 #2

5 2
1 10
5 15
14 50
30 70
99 100
21
3 4 

思路

题意:给出n个区间,求m个区间的最大覆盖,并输出覆盖的区间编号

k个区间交集 = 右端点最小值 - 左端点最大值

按区间左端点从小到大排序,用优先队列(小顶堆)维护k个右端点,保证每次选的都是最小的右端点r,用r减去这k个区间的最大l(排序后当前就是最大的l),此时求得即为被覆盖k次的区间的长度。不断进行,更新长度最大值。

int n, m;

struct node {
	int l, r;
	int id;
	bool operator<(const node &A) const {
		if (l == A.l) return r < A.r;
		return l < A.l;
	}
} a[N];

void solve() {
	cin >> n >> m;
	rep(i, 1, n) cin >> a[i].l >> a[i].r, a[i].id = i;
	sort(a + 1, a + 1 + n);
	pql q;
	int mx = 0, xx, yy;
	rep(i, 1, n) {
		q.push(a[i].r);
		if (q.sz > m) q.pop(); 
		int len = q.top() - a[i].l + 1; 
		if (q.sz == m && mx < len) {
			mx = len; 
			xx = a[i].l; 
			yy = q.top(); 
		} 
	}
	cout << mx << endl; 
	if (mx == 0) xx = 2e9, yy = -2e9; 
	for (int i = 1, j = 0; i <= n && j < m; i++) {
		if (a[i].l <= xx && a[i].r >= yy) {
			j++; 
			cout << a[i].id << ' ';
		} 
	}
}
引用中提供的代码是一个用于检查两个时间区间是否有交集的函数。这个函数通过比较两个时间区间的开始时间和结束时间,判断它们是否有重叠的部分。如果有重叠的部分,则返回false,表示存在冲突;如果没有重叠的部分,则返回true,表示没有冲突。 你提到了moment时间区间交集问题,moment是一个用于处理日期和时间的JavaScript库。如果你想在moment中检查两个时间区间交集,可以使用moment.range.intersect方法。这个方法可以接受两个moment对象作为参数,判断它们是否有交集。 下面是一个使用moment库的例子,来检查两个时间区间交集: ```javascript const moment = require('moment'); // 定义第一个时间区间 const start1 = moment('2022-01-01 08:00'); const end1 = moment('2022-01-01 12:00'); const range1 = moment.range(start1, end1); // 定义第二个时间区间 const start2 = moment('2022-01-01 10:00'); const end2 = moment('2022-01-01 14:00'); const range2 = moment.range(start2, end2); // 检查两个时间区间交集 const intersect = range1.intersect(range2); if (intersect) { // 有交集 console.log('时间区间交集'); } else { // 没有交集 console.log('时间区间没有交集'); } ``` 在上述例子中,我们使用moment库定义了两个时间区间,然后使用intersect方法检查它们是否有交集。根据结果,我们可以得知这两个时间区间是否有交集。 希望以上信息对你有帮助。<span class="em">1</span> #### 引用[.reference_title] - *1* [js判断两个时间段,是否有交集](https://blog.csdn.net/qq_35864320/article/details/103211539)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ღCauchyོꦿ࿐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值