侧边栏壁纸
  • 累计撰写 192 篇文章
  • 累计创建 2 个标签
  • 累计收到 87 条评论

【题解】区间交集(二)

Allen Best
2022-10-13 / 0 评论 / 0 点赞 / 62 阅读 / 1,009 字
温馨提示:
本文最后更新于 2023-04-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目描述
给定 n 个数轴上的闭区间,请统计有多少对区间的交集不是空集。

输入格式
第一行:一个整数 n;
接下来 n 行:每行两个整数 a_i与 b_i ,表示一个闭区间的左端点与右端点。

输出格式
单个整数:表示有多少对区间的交集不是空集。

数据范围
对于 30% 的数据,1≤n≤5,000;
对于 60% 的数据,1≤n≤20,000;
对于 100% 的数据,1≤n≤300,000;
1≤ai≤bi≤1,000,000;

【题解】

1、暴力枚举的方式
统计多少对满足题意,暴力枚举,N*N的时间复杂度。通过for 枚举 i :1-n,j:i+1 -n,统计有多少交集。但这种只能得大约60分。
2、优化思想:
假设 现有区间[x,y] 和[a,b]。计算这两个区间是否交集,可以考虑若 各区间左端点有序,那么判断这两个区间是否有交集,只需要判断 y 和 a 的大小关系即可,若 y > a,则这两个区间必有交集。
对全部区间可以这样考虑:
将所有区间左端点按照从小到大排序,那么对第i个区间,考虑第i+1 ~ n个区间,由于这些区间中左端点均大于第i个区间,因此只需要判断 y(第i个区间右端点) 与这些区间的左端点关系即可。(二分)
程序代码

#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
int n,ans;
struct Sec
{
	int l,r;
}a[300010];
bool cmp(Sec s1,Sec s2)
{
	return s1.l < s2.l || s1.l == s2.l && s1.r < s2.r;
}
int check(int x)
{
	int l = 1,r = n,mid;
	int ret = n + 1;
	while(l <= r)
	{
		mid = l + r >> 1;
		if(a[mid].l > x)
		{
			ret = mid;
			r = mid - 1;
		}
		else l = mid + 1;
	}
	return ret;
}
signed main()
{
	cin >> n;
	for(int i = 1;i <= n;i ++) scanf("%d%d",&a[i].l,&a[i].r);
	sort(a + 1,a + n + 1,cmp);
	for(int i = 1;i <= n;i ++) ans += check(a[i].r) - i - 1;
	cout << ans << endl;
	return 0;
}
0
博主关闭了当前页面的评论