You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
// 柯朵莉树模板
struct Node {
int l, r; // l和r表示这一段的起点和终点
mutable int v; // v表示这一段上所有元素相同的值是多少,注意关键字 mutable,使得set中结构体属性可修改
bool operator<(const Node &b) const {
return l < b.l; // 规定按照每段的左端点排序
}
};
set<Node> s; // 柯朵莉树的区间集合
// 分裂:[l,x-1],[x,r]
set<Node>::iterator split(int x) {
auto it = s.lower_bound({x});
if (it != s.end() && it->l == x) return it; // 一击命中
it--; // 没有找到就减1个继续找
if (it->r < x) return s.end(); // 真的没找到,返回s.end()
int l = it->l, r = it->r, v = it->v; // 没有被返回,说明找到了,记录下来,防止后面删除时被破坏
s.erase(it); // 删除整个区间
s.insert({l, x - 1, v}); //[l,x-1]拆分
return s.insert({x, r, v}).first; //[x,r]拆分
}
// 区间加
void add(int l, int r, int v) {
auto R = split(r + 1), L = split(l);
for (; L != R; L++) L->v += v;
}
// 区间赋值
void assign(int l, int r, int v) {
auto R = split(r + 1), L = split(l);
s.erase(L, R); // 删除旧区间
s.insert({l, r, v}); // 增加新区间
}
// 区间查询
int query(int l, int r, bool v) {
int sum = 0, res = 0;
auto R = split(r + 1), L = split(l);
for (; L != R; L++)
if (L->v == v)
sum += L->r - L->l + 1;
else {
res = max(res, sum);
sum = 0;
}
return res;
}
int main() {
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
int n;
cin >> n;
int mi = INF, mx = -INF;
// 柯朵莉树需要进行初始化,而且最好带0防止RE
s.insert({0, 1000000, 0});
while (n--) {
int l, r;
cin >> l >> r;
assign(l, r - 1, 1); // 这里如果l=r=1按这样[1,0],就会出现边界问题,所以上面最初时加入了{0,1000000}
mi = min(mi, l);
mx = max(mx, r);
}
cout << query(mi, mx, 1) << ' ' << query(mi, mx, 0);
return 0;
}