[AT2645] [ARC076 F] Exhausted

本文探讨了一个算法竞赛问题,其中参与者需要在数轴上的椅子中找到符合特定条件的位置坐下。通过使用排序和小根堆的数据结构,文章提出了一种有效的解决方案,以确定添加额外椅子的最小数量,确保所有参与者都有座位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

洛谷传送门
Atcoder传送门

题意翻译

m m m个椅子在数轴上排列,第 i i i张椅子 ( 1 ≤ i ≤ m ) (1≤i≤m) (1im)的坐标为 i i i。 高桥君和他的朋友一共有 n n n个人。高桥君他们因为玩了太久的游戏,大家的腰和背都很痛,所以他们很有必要坐在椅子上休息一下。高桥君他们每个人坐的椅子的坐标都很讲究,第 i i i个人想坐在坐标在 l i l_i li以下(包括 l i l_i li)的椅子上,或者坐在坐标在 r i r_i ri以上(包括 r i r_i ri)的椅子上。当然,一个的椅子只能坐一个人。 可这样计算下去,可能会让他们不能都坐在椅子上休息。青木君关心高桥君他们的健康,尽可能多地增加椅子,让高桥君他们都能够坐在椅子上休息。 椅子可以添加到任意的实数坐标上,请求出需要添加椅子数量的最小值。

输入输出格式

输入格式

第一行输入两个数 n n n m m m

接下来的第二行到 m + 1 m+1 m+1行依次输入 l [ i ] l[i] l[i] r [ i ] r[i] r[i]

输出格式

输出需要添加的椅子数量的最小值

输入输出样例

输入样例#1:
4 4
0 3
2 3
1 3
3 4
输出样例#1:
0
输入样例#2:
7 6
0 7
1 5
3 6
2 7
1 6
2 6
3 7
输出样例#2:
2
输入样例#3:
3 1
1 2
1 2
1 2
输出样例#3:
2
输入样例#4:
6 6
1 6
1 6
1 5
1 5
2 6
2 6
输出样例#4:
2
输入样例#5:
4 4
0 3
2 3
1 3
3 4
输出样例#5:

输入样例#6:
7 6
0 7
1 5
3 6
2 7
1 6
2 6
3 7
输出样例#6:
2
输入样例#7:
3 1
1 2
1 2
1 2
输出样例#7:
2
输入样例#8:
6 6
1 6
1 6
1 5
1 5
2 6
2 6

数据范围

1 ≦ N , M ≦ 2 × 1 0 5 1 ≦ N,M ≦ 2×10^5 1N,M2×105

0 ≦ l i &lt; r i ≦ M + 1 0 ≦ li &lt; ri ≦ M+1 0li<riM+1

所有的数都是整数

解题分析

如果只有一个限制(如必须 ≤ x ​ \le x​ x), 直接对其排序, 从左向右扫即可。

现在有两个限制, 那么我们可以把一些左端放不下的塞到右边去, 当然是右边 ≥ x \ge x x的限制 x x x越小越好, 这个我们用个小根堆就可以解决。

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <queue>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 200500
template <class T>
IN void in(T &x)
{
	x = 0; R char c = gc;
	for (; !isdigit(c); c = gc);
	for (;  isdigit(c); c = gc)
	x = (x << 1) + (x << 3) + c - 48;
}
int n, m, low, hig, rcnt, ans;
int buf[MX];
struct INFO {int l, r;} dat[MX];
IN bool operator < (const INFO &x, const INFO &y) {return x.l == y.l ? x.r > y.r : x.l < y.l;}
std::priority_queue <int, std::vector <int>, std::greater <int> > pq;
int main(void)
{
	in(n), in(m);
	low = 1, hig = m;
	for (R int i = 1; i <= n; ++i) in(dat[i].l), in(dat[i].r);
	std::sort(dat + 1, dat + 1 + n);
	for (R int i = 1; i <= n; ++i)
	{
		pq.push(dat[i].r);
		if (low <= dat[i].l) ++low;
		else
		{
			buf[++rcnt] = pq.top();
			pq.pop();
		}
	}
	std::sort(buf + 1, buf + 1 + rcnt);
	for (R int i = rcnt; i; --i)
	{
		if (hig >= buf[i] && hig >= low) --hig;
		else ++ans;
	}
	printf("%d", ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值