結果
問題 | No.2292 Interval Union Find |
ユーザー | rniya |
提出日時 | 2023-05-05 22:07:24 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 217 ms / 5,000 ms |
コード長 | 5,878 bytes |
コンパイル時間 | 2,395 ms |
コンパイル使用メモリ | 210,540 KB |
実行使用メモリ | 15,872 KB |
最終ジャッジ日時 | 2024-11-23 07:56:43 |
合計ジャッジ時間 | 12,173 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 74 ms
5,248 KB |
testcase_05 | AC | 115 ms
5,248 KB |
testcase_06 | AC | 70 ms
5,248 KB |
testcase_07 | AC | 106 ms
5,248 KB |
testcase_08 | AC | 112 ms
5,248 KB |
testcase_09 | AC | 112 ms
5,248 KB |
testcase_10 | AC | 103 ms
5,248 KB |
testcase_11 | AC | 97 ms
5,248 KB |
testcase_12 | AC | 115 ms
5,248 KB |
testcase_13 | AC | 84 ms
5,248 KB |
testcase_14 | AC | 91 ms
5,248 KB |
testcase_15 | AC | 94 ms
5,248 KB |
testcase_16 | AC | 90 ms
5,248 KB |
testcase_17 | AC | 103 ms
5,248 KB |
testcase_18 | AC | 164 ms
15,872 KB |
testcase_19 | AC | 193 ms
15,872 KB |
testcase_20 | AC | 190 ms
15,872 KB |
testcase_21 | AC | 175 ms
12,160 KB |
testcase_22 | AC | 178 ms
12,416 KB |
testcase_23 | AC | 179 ms
12,288 KB |
testcase_24 | AC | 172 ms
12,288 KB |
testcase_25 | AC | 189 ms
12,160 KB |
testcase_26 | AC | 184 ms
12,288 KB |
testcase_27 | AC | 181 ms
12,160 KB |
testcase_28 | AC | 183 ms
12,288 KB |
testcase_29 | AC | 178 ms
12,288 KB |
testcase_30 | AC | 178 ms
12,160 KB |
testcase_31 | AC | 178 ms
12,288 KB |
testcase_32 | AC | 186 ms
12,288 KB |
testcase_33 | AC | 184 ms
12,160 KB |
testcase_34 | AC | 185 ms
12,160 KB |
testcase_35 | AC | 194 ms
12,160 KB |
testcase_36 | AC | 193 ms
12,160 KB |
testcase_37 | AC | 217 ms
12,416 KB |
testcase_38 | AC | 197 ms
12,416 KB |
testcase_39 | AC | 195 ms
12,160 KB |
testcase_40 | AC | 189 ms
12,416 KB |
testcase_41 | AC | 47 ms
5,248 KB |
testcase_42 | AC | 52 ms
5,248 KB |
testcase_43 | AC | 59 ms
5,248 KB |
testcase_44 | AC | 67 ms
5,248 KB |
testcase_45 | AC | 67 ms
5,248 KB |
testcase_46 | AC | 74 ms
5,248 KB |
testcase_47 | AC | 81 ms
5,248 KB |
ソースコード
#include <bits/stdc++.h> #ifdef LOCAL #include <debug.hpp> #else #define debug(...) void(0) #endif template <typename S, typename T> struct IntervalManager { struct node { T l, r; S x; node(T l, T r, S x) : l(l), r(r), x(x) {} constexpr bool operator<(const node& rhs) const { return l != rhs.l ? l < rhs.l : r < rhs.r; } }; const S id = S(); std::set<node> s; IntervalManager() {} IntervalManager(const std::vector<S>& v) { std::vector<node> tmp; for (size_t l = 0; l < v.size();) { size_t r = l; while (r < v.size() and v[l] == v[r]) r++; tmp.emplace_back(l, r, v[l]); l = r; } s = std::set<node>(tmp.begin(), tmp.end()); } typename std::set<node>::iterator getItr(const T& x) const { auto itr = s.upper_bound(node(x, std::numeric_limits<T>::max(), id)); if (itr == s.begin()) return s.end(); itr = prev(itr); return itr->l <= x and x < itr->r ? itr : s.end(); } node getSeg(const T& x) const { auto itr = getItr(x); return itr != s.end() ? *itr : node(x, x + 1, id); } S get(const T& x) const { auto seg = getSeg(x); return seg.x; } S operator[](const T& x) const { return get(x); } template <typename ADD, typename DEL> void apply(T l, T r, const S& x, const ADD& add, const DEL& del) { auto itr = s.lower_bound(node(l, std::numeric_limits<T>::min(), id)); while (itr != s.end() and itr->l <= r) { if (itr->l == r) { if (itr->x == x) { del(itr->l, itr->r, itr->x); r = itr->r; itr = s.erase(itr); } break; } if (itr->r <= r) { del(itr->l, itr->r, itr->x); itr = s.erase(itr); } else { if (itr->x == x) { r = itr->r; del(itr->l, itr->r, itr->x); itr = s.erase(itr); } else { del(itr->l, r, itr->x); node tmp = *itr; itr = s.erase(itr); itr = s.emplace_hint(itr, r, tmp.r, tmp.x); } } } if (itr != s.begin()) { itr = prev(itr); if (itr->r == l) { if (itr->x == x) { del(itr->l, itr->r, itr->x); l = itr->l; itr = s.erase(itr); } } else if (l < itr->r) { if (itr->x == x) { del(itr->l, itr->r, itr->x); l = std::min(l, itr->l); r = std::max(r, itr->r); itr = s.erase(itr); } else { if (r < itr->r) { itr = s.emplace_hint(next(itr), r, itr->r, itr->x); itr = prev(itr); } del(l, std::min(r, itr->r), itr->x); node tmp = *itr; itr = s.erase(itr); itr = s.emplace_hint(itr, tmp.l, l, tmp.x); } } } add(l, r, x); s.emplace(l, r, x); } void apply(T l, T r, const S& x) { apply( l, r, x, [](T, T, S) {}, [](T, T, S) {}); } friend std::ostream& operator<<(std::ostream& os, const IntervalManager& im) { for (const auto& e : im) os << "([" << e.l << ", " << e.r << "): " << e.x << ") "; os << "\n"; return os; } }; using namespace std; typedef long long ll; #define all(x) begin(x), end(x) constexpr int INF = (1 << 30) - 1; constexpr long long IINF = (1LL << 60) - 1; constexpr int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1}; template <class T> istream& operator>>(istream& is, vector<T>& v) { for (auto& x : v) is >> x; return is; } template <class T> ostream& operator<<(ostream& os, const vector<T>& v) { auto sep = ""; for (const auto& x : v) os << exchange(sep, " ") << x; return os; } template <class T, class U = T> bool chmin(T& x, U&& y) { return y < x and (x = forward<U>(y), true); } template <class T, class U = T> bool chmax(T& x, U&& y) { return x < y and (x = forward<U>(y), true); } template <class T> void mkuni(vector<T>& v) { sort(begin(v), end(v)); v.erase(unique(begin(v), end(v)), end(v)); } template <class T> int lwb(const vector<T>& v, const T& x) { return lower_bound(begin(v), end(v), x) - begin(v); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, Q; cin >> N >> Q; IntervalManager<int, int> IM; auto add = [&](int l, int r, int x) {}; auto del = [&](int l, int r, int x) {}; for (; Q--;) { int type; cin >> type; if (type == 1) { int L, R; cin >> L >> R; IM.apply(L, R, 1, add, del); } else if (type == 2) { int L, R; cin >> L >> R; IM.apply(L, R, 0, add, del); } else if (type == 3) { int u, v; cin >> u >> v; if (u > v) swap(u, v); if (u == v) { cout << 1 << '\n'; continue; } auto seg = IM.getSeg(u); cout << (seg.x == 1 and seg.r > v - 1) << '\n'; } else { int v; cin >> v; auto seg = IM.getSeg(v); debug(v, seg.l, seg.r); int ans = (seg.x == 0 ? 1 : seg.r - seg.l + 1); auto nseg = IM.getSeg(v - 1); if (seg.l != nseg.l and seg.r != nseg.r and nseg.x == 1) ans += nseg.r - nseg.l; cout << ans << '\n'; } } return 0; }