【大联盟】20230706 T3 Interesting DS Problem(interesting) QOJ2559 【Endless Road】

题目描述#

here

题解#

首先,我们对所有区间离散化,删除一个区间时,我们暴力删除内部还存在的子区间。

如果没有区间包含是好做的,因为我们删除一个子区间时,将区间按照左端点排序,可发现包含这个子区间的区间是连续的一个区间。

现在考虑有区间包含怎么做。我们考虑维护出当前所有不包含别的区间的集合。因为若一个区间包含另一个区间,那么它一定在另一个区间之后删除,所以我们当前就不需要管它了。

我们找到当前要删除的区间后,我们就加入新的不包含别的区间的区间。有个暴力做法是主席树优化建图。不过还有别的做法,我们找到按照左端点排序的上一个区间 [l1,r1] 和下一个区间 [l2,r2],则我们每次找到剩下区间 [l,r],满足 r<r2,于是显然满足 l<l2,并且是所有可行区间中 l 最大的,若 l>l1 则结束。然后更新 l2l,r2r

容易发现,这样可以找到所有新的合法区间。因为新的合法区间需要满足只包含 [l,r],不包含别的区间,也就是不包含按左端点排序后与 [l,r] 相邻的两个区间。

时间复杂度 O(nlogn)

代码#

记录

Copy
#include <bits/stdc++.h> #define ls num << 1 #define rs ls | 1 #define li ls, l, mid #define ri rs, mid + 1, r #define SZ(x) (int) x.size() - 1 #define all(x) x.begin(), x.end() #define ms(x, y) memset(x, y, sizeof x) #define F(i, x, y) for (int i = (x); i <= (y); i++) #define DF(i, x, y) for (int i = (x); i >= (y); i--) using namespace std; typedef long long ll; typedef unsigned long long ull; template <typename T> void chkmax(T& x, T y) { x = max(x, y); } template <typename T> void chkmin(T& x, T y) { x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } const int N = 5e5 + 10; pair <int, int> a[N], b[N]; int id[N], seg1[N << 2], t[N], seg2[N << 2], ss[N << 2], tmp[N], tot, tag[N << 2], maxn[N << 2]; void add(int x, int y) { for (; x <= tot; x += x & -x) t[x] += y; } int query(int x) { int ans = 0; for (; x; x -= x & -x) ans += t[x]; return ans; } void pushup1(int num) { if (seg1[ls] && (!seg1[rs] || a[seg1[ls]].second < a[seg1[rs]].second)) seg1[num] = seg1[ls]; else seg1[num] = seg1[rs]; } priority_queue <pair <int, int>, vector <pair <int, int>>, greater <pair <int, int>>> tt[N << 2]; void modify1(int num, int l, int r, int x) { if (l == r) { tt[num].emplace(a[x].second, x); seg1[num] = tt[num].top().second; return; } int mid = (l + r) >> 1; if (mid >= a[x].first) modify1(li, x); else modify1(ri, x); pushup1(num); } void mmodify1(int num, int l, int r, int x) { if (l == r) { tt[num].pop(); seg1[num] = tt[num].size() ? tt[num].top().second : 0; return; } int mid = (l + r) >> 1; if (mid >= a[x].first) mmodify1(li, x); else mmodify1(ri, x); pushup1(num); } int query1(int num, int l, int r, int x, int y) { if (!seg1[num] || a[seg1[num]].second >= y) return -1; if (l == r) return seg1[num]; int mid = (l + r) >> 1; if (mid + 1 < x) { int t = query1(ri, x, y); if (~t) return t; } return query1(li, x, y); } void down(int num, int x) { tag[num] += x; seg2[num] += x; } void pushdown(int num) { if (tag[num]) { down(ls, tag[num]), down(rs, tag[num]); tag[num] = 0; } } void pushup2(int num) { if ((seg2[ls] < seg2[rs]) || (seg2[ls] == seg2[rs] && id[ss[ls]] < id[ss[rs]])) { seg2[num] = seg2[ls]; ss[num] = ss[ls]; } else { seg2[num] = seg2[rs]; ss[num] = ss[rs]; } maxn[num] = max(maxn[ls], maxn[rs]); } void modify2(int num, int l, int r, int x, int y) { if (l == r) { seg2[num] = y; maxn[num] = a[x].second - 1; if (y == 1e9) ss[num] = 0; else ss[num] = x; return; } pushdown(num); int mid = (l + r) >> 1; if (mid >= a[x].first) modify2(li, x, y); else modify2(ri, x, y); pushup2(num); } void change(int num, int l, int r, int L, int R, int x) { if (L <= l && r <= R) return down(num, x); pushdown(num); int mid = (l + r) >> 1; if (mid >= L) change(li, L, R, x); if (mid < R) change(ri, L, R, x); pushup2(num); } int prv(int num, int l, int r, int x) { if (!ss[num]) return -1; if (l == r) return ss[num]; int mid = (l + r) >> 1; if (mid + 1 < a[x].first) { int t = prv(ri, x); if (~t) return t; } return prv(li, x); } int nxt(int num, int l, int r, int x) { if (!ss[num]) return -1; if (l == r) return ss[num]; int mid = (l + r) >> 1; if (mid > a[x].first) { int t = nxt(li, x); if (~t) return t; } return nxt(ri, x); } int query2(int num, int l, int r, int x) { if (l == r) return l; int mid = (l + r) >> 1; if (maxn[ls] >= x) return query2(li, x); return query2(ri, x); } bool vis[N]; void zhk() { tot = 0; int n; read(n); F(i, 1, n * 2) t[i] = 0, vis[i] = false; F(i, 1, n * 8) { seg2[i] = 1e9; seg1[i] = tag[i] = ss[i] = maxn[i] = 0; while (tt[i].size()) tt[i].pop(); } F(i, 1, n) read(a[i].first), read(a[i].second), tmp[++tot] = a[i].first, tmp[++tot] = a[i].second, id[i] = i; sort(tmp + 1, tmp + tot + 1); tot = unique(tmp + 1, tmp + tot + 1) - tmp - 1; F(i, 1, n) a[i].first = lower_bound(tmp + 1, tmp + tot + 1, a[i].first) - tmp, a[i].second = lower_bound(tmp + 1, tmp + tot + 1, a[i].second) - tmp; sort(id + 1, id + n + 1, [&] (int x, int y) { if (a[x].first == a[y].first) return a[x].second > a[y].second; return a[x].first < a[y].first; }); F(i, 1, n) b[i] = a[id[i]]; swap(a, b); deque <int> q; set <int> s; F(i, 1, tot - 1) add(i, tmp[i + 1] - tmp[i]), s.insert(i); F(i, 1, n) { while (q.size() && a[q.back()].second >= a[i].second) q.pop_back(); q.push_back(i); } ms(vis, false); for (int i: q) { vis[i] = true; modify2(1, 1, tot, i, tmp[a[i].second] - tmp[a[i].first]); } F(i, 1, n) if (!vis[i]) modify1(1, 1, tot, i); F(i, 1, n) { int t = ss[1]; cout << id[t] << " "; modify2(1, 1, tot, t, 1e9); int p = a[t].first == 1 ? -1 : prv(1, 1, tot, t), q = a[t].first == tot ? -1 : nxt(1, 1, tot, t); while (true) { int t = query1(1, 1, tot, (~q) ? a[q].first : tot + 1, (~q) ? a[q].second : tot + 1); if (t == -1) break; if ((~p) && a[t].first <= a[p].first) break; mmodify1(1, 1, tot, t); modify2(1, 1, tot, t, query(a[t].second - 1) - query(a[t].first - 1)); q = t; } while (true) { auto pos = s.lower_bound(a[t].first); if (pos == s.end() || *pos >= a[t].second) break; int x = *pos; s.erase(pos); add(x, tmp[x] - tmp[x + 1]); int pp = query2(1, 1, tot, x); change(1, 1, tot, pp, x, tmp[x] - tmp[x + 1]); } } cout << '\n'; } signed main() { // freopen("interesting.in", "r", stdin); // freopen("interesting.out", "w", stdout); int T, sid; read(T); while (T--) zhk(); return 0; }
posted @   zhaohaikun  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
CONTENTS