Codeforces Round #613 (Div. 2) Delete a Segment(删除一条边,计算并区间最大数量)

编程入门 行业动态 更新时间:2024-10-26 19:41:52

Codeforces Round #613 (Div. 2) Delete a Segment(删除一条边,计算并<a href=https://www.elefans.com/category/jswz/34/1766384.html style=区间最大数量)"/>

Codeforces Round #613 (Div. 2) Delete a Segment(删除一条边,计算并区间最大数量)

E. Delete a Segment

There are nn segments on a OxOx axis [l1,r1][l1,r1], [l2,r2][l2,r2], ..., [ln,rn][ln,rn]. Segment [l,r][l,r] covers all points from ll to rr inclusive, so all xx such that l≤x≤rl≤x≤r.

Segments can be placed arbitrarily  — be inside each other, coincide and so on. Segments can degenerate into points, that is li=rili=ri is possible.

Union of the set of segments is such a set of segments which covers exactly the same set of points as the original set. For example:

  • if n=3n=3 and there are segments [3,6][3,6], [100,100][100,100], [5,8][5,8] then their union is 22 segments: [3,8][3,8] and [100,100][100,100];
  • if n=5n=5 and there are segments [1,2][1,2], [2,3][2,3], [4,5][4,5], [4,6][4,6], [6,6][6,6] then their union is 22 segments: [1,3][1,3] and [4,6][4,6].

Obviously, a union is a set of pairwise non-intersecting segments.

You are asked to erase exactly one segment of the given nn so that the number of segments in the union of the rest n−1n−1 segments is maximum possible.

For example, if n=4n=4 and there are segments [1,4][1,4], [2,3][2,3], [3,6][3,6], [5,7][5,7], then:

  • erasing the first segment will lead to [2,3][2,3], [3,6][3,6], [5,7][5,7] remaining, which have 11 segment in their union;
  • erasing the second segment will lead to [1,4][1,4], [3,6][3,6], [5,7][5,7] remaining, which have 11 segment in their union;
  • erasing the third segment will lead to [1,4][1,4], [2,3][2,3], [5,7][5,7] remaining, which have 22 segments in their union;
  • erasing the fourth segment will lead to [1,4][1,4], [2,3][2,3], [3,6][3,6] remaining, which have 11 segment in their union.

Thus, you are required to erase the third segment to get answer 22.

Write a program that will find the maximum number of segments in the union of n−1n−1 segments if you erase any of the given nn segments.

Note that if there are multiple equal segments in the given set, then you can erase only one of them anyway. So the set after erasing will have exactly n−1n−1 segments.

Input

The first line contains one integer tt (1≤t≤1041≤t≤104) — the number of test cases in the test. Then the descriptions of tt test cases follow.

The first of each test case contains a single integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the number of segments in the given set. Then nn lines follow, each contains a description of a segment — a pair of integers lili, riri (−109≤li≤ri≤109−109≤li≤ri≤109), where lili and riri are the coordinates of the left and right borders of the ii-th segment, respectively.

The segments are given in an arbitrary order.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

Print tt integers — the answers to the tt given test cases in the order of input. The answer is the maximum number of segments in the union of n−1n−1 segments if you erase any of the given nn segments.

链接:

题意:很多条[l,r]边,删除其中一条边,计算并区间最大数量。

题解:(大佬写的,记笔记学习)

#include <bits/stdc++.h>
using namespace std;
#define R register
#define ll long long
#define sum(a, b, mod) (((a) + (b)) % mod)const int MaxN = 1e6 + 10;std::map<int, int> m1, m2;
int n, cnt, l[MaxN], r[MaxN], a[MaxN], s[MaxN];inline void prework()//离散 
{m1.clear(), m2.clear();for (int i = 1; i <= n; i++)m1[l[i]] = m1[r[i]] = 1;cnt = 0;for (std::map<int, int>::iterator it = m1.begin(); it != m1.end(); it++)m2[it->first] = ++cnt;for (int i = 1; i <= n; i++){l[i] = m2[l[i]] * 2 - 1, r[i] = m2[r[i]] * 2 - 1;}
}inline int read()
{int x = 0, f = 1;char ch = getchar();while (ch > '9' || ch < '0'){if (ch == '-')f = 0;ch = getchar();}while (ch <= '9' && ch >= '0')x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();return f ? x : (-x);
}int main()
{int T = read();while (T--){n = read(), cnt = 0;for (int i = 1; i <= n; i++)l[i] = read(), r[i] = read();prework(), cnt = cnt * 2 - 1;	//cnt=离散完,l~r点的数量 for (int i = 1; i <= n; i++)	//差分 a[l[i]]++, a[r[i] + 1]--;for (int i = 1; i <= cnt; i++)	//求各点的值 a[i] += a[i - 1];int num = 0, ans = -1000000;for (int i = 1; i <= cnt; i++)  {s[i] = s[i - 1];	//s[i]为计算a[i]=1的前缀和数量 num += (a[i] && !a[i - 1]);	//计算有多少并区间 if (a[i] > 1 && a[i - 1] <= 1)++s[i];}for (int i = 1; i <= n; i++)//枚举边,产生多少区间。 {int cur = s[r[i]] - s[l[i] - 1] + ((a[l[i]] > 1) && (a[l[i] - 1] > 1)) - 1;ans = std::max(ans, cur);}printf("%d\n", num + ans);for (int i = 0; i <= cnt * 2; i++)a[i] = s[i] = 0;}return 0;
}

 

更多推荐

Codeforces Round #613 (Div. 2) Delete a Segment(删除一条边,计算并区间最大数量)

本文发布于:2024-02-25 02:35:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1697498.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:区间   数量   Codeforces   Div   Segment

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!