思想
首先我们用差分数组和前缀和把所有的区间都预处理出来,然后我们统计一下每段充能区间和非充能区间的长度,最后求一下最大长度。
注意,当是i是1,i-1是非0时,此时i就是充能区间的开始,同时也是非充能区间的结尾。
当i是0,i-1是非0时,i-1是充能区间的结尾,同时也是非充能区间的开始。
code
注意
1.需要注意的是我们预处理差分和前缀和数字的时候不要从0处理到n,而是根据题目输入的n个[l,r]区间中统计出最小的l和最大的r,在这个[minl,maxr]之间预处理。
2.注意在统计结果的时候我们的遍历区间范围是[minl,maxr+1]而不是[min,maxr]
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int a[N], d[N];
int minl = 0x3f3f3f3f, maxr = -0x3f3f3f3f;
int ans1, ans2;
int start1, end1, start2 = 0x3f3f3f3f, end2;
int n;
int main()
{
cin >> n;
while (n--)
{
int l, r; cin >> l >> r;
minl = min(minl, l);
maxr = max(maxr, r);
d[l]++, d[r + 1]--;
}
for (int i = minl; i <= maxr; i++)
{
a[i] = a[i - 1] + d[i];
}
// for (int i = minl; i <= maxr; i++)
// {
// cout << a[i];
// }
for (int i = minl; i <= maxr + 1; i++)
{
if (a[i] != 0 && a[i - 1] == 0)
{
end2 = start1 = i;
ans2 = max(ans2, end2 - start2);
}
if (a[i] == 0 && a[i - 1] != 0)
{
end1 = start2 = i - 1;
ans1 = max(ans1, end1 - start1);
}
}
cout << ans1 << " " << ans2 << endl;
return 0;
}