C. Medium Design Codeforces Round 904 (Div. 2)

Problem - C - Codeforces

The main idea of ​​the question: There is an array with a length of m that is initially all zeros and has n intervals [li, ri]. Each time you select an interval, you must add 1 to all the numbers in the interval. You are required to select some intervals so that the maximum value of the array - The minimum value is the maximum, find the difference

1<=n<=1e5;1<=m<=1e9

Idea: Let us assume that the position where the maximum value is obtained is i. If we want to maximize the maximum value, then all intervals containing this position must be selected, and let the large interval formed by removing the overlapping parts of these intervals be [L, R], Then the value position of the minimum value in this interval must be L or R, because if the value position of the minimum value is in LR, then the interval to the left or right of this position can be deleted while the maximum value on the other side is still equal to the original The maximum value and the minimum value become the endpoints of the new large interval.

        So when the minimum value of the entire array is outside [L, R], then the answer is equal to the maximum value. If it is in L or R, then the interval with L as the left endpoint needs to be deleted or the interval with R as the right endpoint needs to be deleted. After deletion, the contribution of these intervals to the maximum and minimum values ​​is 1, so ma-mi remains unchanged after deletion, and the maximum value can be taken in both cases.

        Consider how to find the maximum value of an interval. Because the range of m in this question cannot be an array, we use a pair array to record the endpoints of the interval. The left endpoint is {position, 1}, the right endpoint is {position+1, -1}, and then Sort all endpoints from small to large, traverse the total of up to 2e5 endpoints, maintain the prefix and maintain the maximum value at the same time.

//#include<__msvc_all_public_headers.hpp>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int N = 1e5 + 5;
int n;
pair<int, int>a[N];
void init()
{
	
}
void solve()
{
	cin >> n;
	int m;
	cin >> m;
	init();
	for (int i = 1; i <= n; i++)
	{
		int x, y;
		cin >> x >> y;
		a[i] = { x,y };
	}
	vector<pair<int,int>>num1,num2;
	ll ma = 0;
	for (int i = 1; i <= n; i++)
	{
		if (a[i].first != 1)
		{//左端点不是1的
			num1.push_back({ a[i].first,1 });//左端点是+1
			num1.push_back({ a[i].second + 1,-1 });//右端点是-1
		}
		if (a[i].second != m)
		{//右端点不是m的
			num2.push_back({ a[i].first,1 });
			num2.push_back({ a[i].second + 1,-1 });
		}
	}
	sort(num1.begin(), num1.end());//从小到大排序
	sort(num2.begin(), num2.end());
	int las = 0;//当前的下标
	ll cnt = 0;//差分数组前缀和
	for (int i = 0; i < num1.size(); i++)
	{//遍历所有端点
		if (num1[i].first > las)
		{//下标移动后维护最大值
			ma = max(ma, cnt);
		}
		cnt += num1[i].second;
		las = num1[i].first;
	}
	las = 0, cnt = 0;
	for (int i = 0; i < num2.size(); i++)
	{
		if (num2[i].first > las)
		{
			ma = max(ma, cnt);
		}
		cnt += num2[i].second;
		las = num2[i].first;
	}
	cout << ma;
	cout << '\n';
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	//t = 1;
	while (t--)
	{
		solve();
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/ashbringer233/article/details/133975803