[CCO 2020] Interval Collection
不显然的结论:最多选 \(2\) 个区间。因为多余 \(2\) 个的会导致浪费。
最大公共子区间 未定义
设线段树当前区间为 \(\left [ l, r \right ]\)。
用这个树存下面三个值。
-
\(lt\) 表示左端点在当前区间时最小的右端点;
-
\(rt\) 表示右端点在当前区间时最大的左端点;
-
\(ans\) 表示当前区间中最小公共超区间的长度。
线段树的左右子节点为 \(ls, rs\)。
用 \(rt_{rs}-lt_{ls}\) 更新当前节点的 \(ans\) 就行。
否则
令最大的左端点为 \(L\),最小的右端点为 \(R\)。
答案就是 \(L\) 对应的最小右端点与 \(R\) 对应的最大左端点的差。
#include <bits/stdc++.h>
#define ls p << 1
#define rs p << 1 | 1
#define mid (l + r >> 1)
using namespace std;
inline int read()
{
int f = 0, ans = 0;
char c = getchar();
while (!isdigit(c))
f |= c == '-', c = getchar();
while (isdigit(c))
ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();
return f ? -ans : ans;
}
void write(int x)
{
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
constexpr int N = 1e6 + 5, M = N << 2, inf = 1e9;
int m;
multiset<int> L, R, lt[N], rt[N];
struct Tree
{
struct tree
{
int l, r, ans;
tree() : l(-inf), r(inf), ans(inf) {}
tree(int L, int R, int Ans) : l(L), r(R), ans(Ans) {}
} tr[M];
void update(int p)
{
tr[p] = {max(tr[ls].l, tr[rs].l), min(tr[ls].r, tr[rs].r),
min(min(tr[ls].ans, tr[rs].ans), tr[rs].r - tr[ls].l)};
}
void reupdate(int l, int r, int x, int p)
{
if (l == r)
{
tr[p].l = empty(lt[x]) ? -inf : *rbegin(lt[x]);
tr[p].r = empty(rt[x]) ? inf : *begin(rt[x]);
tr[p].ans = tr[p].r - tr[p].l;
return;
}
if (mid >= x)
reupdate(l, mid, x, ls);
else
reupdate(mid + 1, r, x, rs);
update(p);
}
void reupdate(int x) { reupdate(1, 1e6, x, 1); }
int get() { return tr[1].ans; }
} tr;
signed main()
{
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
ios::sync_with_stdio(NULL);
cin.tie(nullptr), cout.tie(nullptr);
cin >> m;
while (m--)
{
char op;
int l, r;
cin >> op >> l >> r;
if (op == 'A')
{
L.insert(l), R.insert(r);
lt[r].insert(l), rt[l].insert(r);
}
else
{
L.erase(L.find(l)), R.erase(R.find(r));
lt[r].erase(lt[r].find(l)), rt[l].erase(rt[l].find(r));
}
tr.reupdate(l), tr.reupdate(r);
if (*begin(R) <= *rbegin(L))
cout << tr.get();
else
cout << *begin(rt[*rbegin(L)]) - *rbegin(lt[*begin(R)]);
cout << '\n';
}
return 0;
}

浙公网安备 33010602011771号