题解:P12082 [Ynoi1998] Frühlingsbeginn
给定
- 插入一个区间
[l,r) 。 - 删除第
t 次操作插入的区间。 - 给出一个区间
[l,r) ,判断当前可重集合中是否存在一个子集,使得子集中所有区间的并恰好是[l,r) 。
将区间看成四元组
首先区间都是左闭右开的实数区间。考虑记第
判断一个询问时,贪心地把所有子集选上再判断是否有解。这样一定不劣。
分治。记当前分治区间为
先考虑选上所有跨过
以 multiset,非叶子节点维护区间内
接下来考虑不跨过
同样以
最后判断有无解就是是否
一个询问在第一个跨过中点的区间被计算,一个区间在包含她的
之前的代码有些细节问题,现在修了一下。
#include <bits/stdc++.h>
#define eb emplace_back
#define ls(x) ((x) << 1)
#define rs(x) ((x) << 1 | 1)
using namespace std; const int N = 1000005; vector<int> l_[N], r_[N];
struct QR { int l, r, t; }; vector<QR> qr, Qr, Rg, gl[N], gr[N];
struct RG { int l, r, tl, tr; }; vector<RG> rg; bool ans[N], ok[N];
int n, q, l[N], r[N], lp[N], rp[N], Lp[N], Rp[N], lh[N], c, op[N];
struct SGT1 {
multiset<int> s[N]; int t[N << 1]; SGT1 () { fill(t, t + (N << 1), N); }
void U(int x, int l, int r, int k, int v, bool o) {
if (l == r) {
if (o) s[l].emplace(v); else s[l].erase(s[l].find(v));
return void(t[x] = s[l].size() ? *s[l].begin() : N);
}
int m = l + r >> 1;
if (k <= m) U(ls(m), l, m, k, v, o); else U(rs(m), m + 1, r, k, v, o);
t[x] = min(t[ls(m)], t[rs(m)]);
}
int Q(int x, int l, int r, int ql, int qr, int v) {
if (t[x] > v) return 0; if (l == r) return l; int m = l + r >> 1, k = 0;
if (ql <= m) k = Q(ls(m), l, m, ql, qr, v); if (k) return k;
return Q(rs(m), m + 1, r, ql, qr, v);
}
} t1;
struct SGT2 {
multiset<int> s[N]; int t[N << 1];
void U(int x, int l, int r, int k, int v, bool o) {
if (l == r) {
if (o) s[l].emplace(v); else s[l].erase(s[l].find(v));
return void(t[x] = s[l].size() ? *s[l].rbegin() : 0);
}
int m = l + r >> 1;
if (k <= m) U(ls(m), l, m, k, v, o); else U(rs(m), m + 1, r, k, v, o);
t[x] = max(t[ls(m)], t[rs(m)]);
}
int Q(int x, int l, int r, int ql, int qr, int v) {
if (t[x] < v) return 0; if (l == r) return l; int m = l + r >> 1, k = 0;
if (qr > m) k = Q(rs(m), m + 1, r, ql, qr, v); if (k) return k;
return Q(ls(m), l, m, ql, qr, v);
}
} t2;
struct SGT3 {
int s[N << 1], t[N << 1];
void B(int x, int l, int r) {
s[x] = N; t[x] = 0; if (l == r) return;
int m = l + r >> 1; B(ls(m), l, m); B(rs(m), m + 1, r);
}
void U(int x, int v) { s[x] = max(s[x], v); t[x] = max(t[x], v); }
void U(int x, int l, int r, int ql, int qr, int v) {
if (ql <= l && r <= qr) return U(x, v); int m = l + r >> 1;
if (ql <= m) U(ls(m), l, m, ql, qr, v);
if (qr > m) U(rs(m), m + 1, r, ql, qr, v);
s[x] = max(min(s[ls(m)], s[rs(m)]), t[x]);
}
void C(int x, int l, int r, int k, int v) {
if (l == r) return void(s[x] = v); int m = l + r >> 1;
U(ls(m), t[x]); U(rs(m), t[x]); t[x] = 0;
if (k <= m) C(ls(m), l, m, k, v); else C(rs(m), m + 1, r, k, v);
s[x] = min(s[ls(m)], s[rs(m)]);
}
int Q(int x, int l, int r) {
if (l == r) return l; int m = l + r >> 1;
return s[ls(m)] < s[rs(m)] ? Q(ls(m), l, m) : Q(rs(m), m + 1, r);
}
} t3;
struct SGT4 {
int s[N << 1], t[N << 1];
void B(int x, int l, int r) {
s[x] = 0; t[x] = N; if (l == r) return;
int m = l + r >> 1; B(ls(m), l, m); B(rs(m), m + 1, r);
}
void U(int x, int v) { s[x] = min(s[x], v); t[x] = min(t[x], v); }
void U(int x, int l, int r, int ql, int qr, int v) {
if (ql <= l && r <= qr) return U(x, v); int m = l + r >> 1;
if (ql <= m) U(ls(m), l, m, ql, qr, v);
if (qr > m) U(rs(m), m + 1, r, ql, qr, v);
s[x] = min(max(s[ls(m)], s[rs(m)]), t[x]);
}
void C(int x, int l, int r, int k, int v) {
if (l == r) return void(s[x] = v); int m = l + r >> 1;
U(ls(m), t[x]); U(rs(m), t[x]); t[x] = N;
if (k <= m) C(ls(m), l, m, k, v); else C(rs(m), m + 1, r, k, v);
s[x] = max(s[ls(m)], s[rs(m)]);
}
int Q(int x, int l, int r) {
if (l == r) return l; int m = l + r >> 1;
return s[ls(m)] > s[rs(m)] ? Q(ls(m), l, m) : Q(rs(m), m + 1, r);
}
} t4;
void lzyqwq(int l, int r, vector<QR> &qr, vector<RG> &rg) {
if (!qr.size() || !rg.size()) return;
if (l == r) {
for (RG i : rg) Rg.eb(QR{i.l, i.r, i.tl}), Rg.eb(QR{-i.l, i.r, i.tr + 1});
stable_sort(qr.begin(), qr.end(), [&](QR u, QR v) { return u.t < v.t; });
stable_sort(Rg.begin(), Rg.end(), [&](QR u, QR v) { return u.t < v.t; });
for (int i = 0, j = 0, d = 0; i < qr.size(); ++i) {
for (; j < Rg.size() && Rg[j].t <= qr[i].t; ++j)
d += abs(Rg[j].l) / Rg[j].l;
ans[qr[i].t] = (d > 0);
}
qr.clear(); rg.clear(); Rg.clear(); return;
}
int m = l + r >> 1; c = 0;
for (QR i : qr)
if (i.l <= m && i.r > m) {
Qr.eb(i); Lp[i.t] = m + 1; Rp[i.t] = m; lh[++c] = i.t;
}
if (c) {
for (RG i : rg)
if (i.l <= m && i.r > m)
Rg.eb(QR{i.l, i.r, i.tl}), Rg.eb(QR{-i.l, i.r, i.tr + 1});
stable_sort(Qr.begin(), Qr.end(), [&](QR u, QR v) { return u.t < v.t; });
stable_sort(Rg.begin(), Rg.end(), [&](QR u, QR v) { return u.t < v.t; });
for (int i = 0, j = 0; i < c; ++i) {
for (; j < Rg.size() && Rg[j].t <= Qr[i].t; ++j)
t1.U(1, 1, n, abs(Rg[j].l), Rg[j].r, abs(Rg[j].l) == Rg[j].l);
lp[Qr[i].t] = t1.Q(1, 1, n, Qr[i].l, n, Qr[i].r);
if (!lp[Qr[i].t]) lp[Qr[i].t] = m + 1;
if (i == c - 1)
for (--j; j >= 0; --j)
t1.U(1, 1, n, abs(Rg[j].l), Rg[j].r, abs(Rg[j].l) != Rg[j].l);
}
for (int i = 0, j = 0; i < c; ++i) {
for (; j < Rg.size() && Rg[j].t <= Qr[i].t; ++j)
t2.U(1, 1, n, Rg[j].r, abs(Rg[j].l), abs(Rg[j].l) == Rg[j].l);
rp[Qr[i].t] = t2.Q(1, 1, n, 1, Qr[i].r, Qr[i].l);
if (!rp[Qr[i].t]) rp[Qr[i].t] = m;
if (i == c - 1)
for (--j; j >= 0; --j)
t2.U(1, 1, n, Rg[j].r, abs(Rg[j].l), abs(Rg[j].l) != Rg[j].l);
}
for (int i = 0; i < c; ++i)
l_[Qr[i].l].eb(i + 1), r_[Qr[i].r].eb(i + 1), lh[i + 1] = Qr[i].t;
Qr.clear(); Rg.clear(); t3.B(1, 1, c); t4.B(1, 1, c);
for (auto [l, r, tl, tr] : rg) {
if (l <= m && r > m) continue;
int sl = lower_bound(lh + 1, lh + c + 1, tl) - lh,
sr = upper_bound(lh + 1, lh + c + 1, tr) - lh - 1;
if (sl > sr) continue;
if (r <= m) gl[l].eb(QR{sl, sr, r + 1});
else gr[r].eb(QR{sl, sr, l - 1});
}
for (int i = l, p; i <= m; ++i) {
for (int j : l_[i]) t3.C(1, 1, c, j, i); l_[i].clear();
for (auto [l, r, v] : gl[i]) t3.U(1, 1, c, l, r, v); gl[i].clear();
while (t3.s[1] == i) Lp[lh[p = t3.Q(1, 1, c)]] = i, t3.C(1, 1, c, p, N);
}
for (int i = r, p; i > m; --i) {
for (int j : r_[i]) t4.C(1, 1, c, j, i); r_[i].clear();
for (auto [l, r, v] : gr[i]) t4.U(1, 1, c, l, r, v); gr[i].clear();
while (t4.s[1] == i) Rp[lh[p = t4.Q(1, 1, c)]] = i, t4.C(1, 1, c, p, 0);
}
for (QR i : qr)
if (i.l <= m && i.r > m)
ans[i.t] = (lp[i.t] <= Lp[i.t] && rp[i.t] >= Rp[i.t]);
}
vector<QR> l_, r_; vector<RG> L_, R_;
for (QR i : qr) if (i.r <= m) l_.eb(i); else if (i.l > m) r_.eb(i);
for (RG i : rg) if (i.r <= m) L_.eb(i); else if (i.l > m) R_.eb(i);
qr.clear(); rg.clear(); lzyqwq(l, m, l_, L_); lzyqwq(m + 1, r, r_, R_);
l_.clear(); r_.clear(); L_.clear(); R_.clear();
}
int main() {
scanf("%d%d", &n, &q); --n;
for (int i = 1; i <= q; ++i) {
scanf("%d%d", &op[i], &l[i]);
if (op[i] == 1) scanf("%d", &r[i]);
else if (op[i] ^ 3)
rg.eb(RG{l[l[i]], r[l[i]] - 1, l[i], i - 1}), ok[l[i]] = 1;
else scanf("%d", &r[i]), qr.eb(QR{l[i], r[i] - 1, i});
}
for (int i = 1; i <= q; ++i)
if (op[i] == 1 && !ok[i]) rg.eb(RG{l[i], r[i] - 1, i, q});
lzyqwq(1, n, qr, rg);
for (int i = 1; i <= q; ++i) if (op[i] == 3) puts(ans[i] ? "Y" : "N"); return 0;
}