P2082 区间覆盖(加强版)

P2082 区间覆盖(加强版)

题目

已知有 N 个区间,每个区间的范围是 [si,ti],请求出区间覆盖后的总长。

输入

第一行一个正整数 N,表示区间个数。

接下来 N 行,每行两个正整数,表示 siti

输出

共一行,一个正整数,为覆盖后的区间总长。

样例

输入

3
1 100000
200001 1000000
100000000 100000001

输出

900002

提示

对于 40% 的数据,N10001si<ti10000

对于 100% 的数据 ,N1051si<ti1017


思路

在分析这道题之前先学习一下“区间合并”的问题:数轴上有 n 个闭区间 [ai,bi],尽量选择少的区间覆盖一个指定的区间 [s,t]

这是“区间覆盖问题”,分析:将区间左端点从小到大排序,如果第一个区间的左端点 a1 大于 s,无解。否则依次枚举起点 ai 小于 s 的区间,记录 bi 的最大值。如上图,区间 1、区间 2、区间 3 的左端点均小于 s,其中右端点 b2 为最大值,记录下来。如果 b2 依然小于 s 则无解,否则 s 被更新成 b2,答案累加 1。按照类似的方式继续判断区间 4、区间 5

按照上述方法,排序后从左到右依次枚举区间,复杂度为 O(n)

回归本题,同样是一道“区间合并”的问题,看到区间问题容易想到贪心的方法,将区间左端点 L 排序,然后从左到右维护,R 表示已经贪心到的最右端的边界,如果当前的右边界大于等于 R 就加上不重复覆盖的区间长度,同时更新 R


代码

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 5;
long long n, R, ans;

struct Range
{
	long long l, r;
	bool operator < (const Range v) const
	{
		return l < v.l;
	}
} a[MAXN];

int main()
{
	scanf("%d", &n);
	for (long long i = 1; i <= n; i ++ )
		scanf("%ld %ld", &a[i].l, &a[i].r);
	sort(a + 1, a + n + 1);
	for (long long i = 1; i <= n; i ++ )
	{
		if (R <= a[i].r)
		{
			ans += a[i].r - max(R, a[i].l) + 1;
			R = a[i].r + 1;
		}
	}
	printf("%ld", ans);
	return 0;
}
posted @   IronMan_PZX  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
Title
点击右上角即可分享
微信分享提示