結果
問題 | No.2292 Interval Union Find |
ユーザー | じきお。 |
提出日時 | 2024-12-22 21:47:37 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 307 ms / 5,000 ms |
コード長 | 3,502 bytes |
コンパイル時間 | 3,526 ms |
コンパイル使用メモリ | 254,400 KB |
実行使用メモリ | 22,144 KB |
最終ジャッジ日時 | 2024-12-22 21:47:53 |
合計ジャッジ時間 | 16,122 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,816 KB |
testcase_03 | AC | 2 ms
6,820 KB |
testcase_04 | AC | 72 ms
6,816 KB |
testcase_05 | AC | 110 ms
6,816 KB |
testcase_06 | AC | 69 ms
6,816 KB |
testcase_07 | AC | 101 ms
6,816 KB |
testcase_08 | AC | 107 ms
6,820 KB |
testcase_09 | AC | 107 ms
6,820 KB |
testcase_10 | AC | 96 ms
6,816 KB |
testcase_11 | AC | 93 ms
6,816 KB |
testcase_12 | AC | 111 ms
6,816 KB |
testcase_13 | AC | 82 ms
6,820 KB |
testcase_14 | AC | 86 ms
6,820 KB |
testcase_15 | AC | 90 ms
6,816 KB |
testcase_16 | AC | 86 ms
6,816 KB |
testcase_17 | AC | 100 ms
6,820 KB |
testcase_18 | AC | 207 ms
22,144 KB |
testcase_19 | AC | 297 ms
22,144 KB |
testcase_20 | AC | 307 ms
22,144 KB |
testcase_21 | AC | 241 ms
14,464 KB |
testcase_22 | AC | 248 ms
14,464 KB |
testcase_23 | AC | 231 ms
14,464 KB |
testcase_24 | AC | 233 ms
14,464 KB |
testcase_25 | AC | 231 ms
14,336 KB |
testcase_26 | AC | 236 ms
14,336 KB |
testcase_27 | AC | 233 ms
14,336 KB |
testcase_28 | AC | 236 ms
14,464 KB |
testcase_29 | AC | 251 ms
14,336 KB |
testcase_30 | AC | 236 ms
14,464 KB |
testcase_31 | AC | 237 ms
14,464 KB |
testcase_32 | AC | 237 ms
14,336 KB |
testcase_33 | AC | 237 ms
14,336 KB |
testcase_34 | AC | 240 ms
14,336 KB |
testcase_35 | AC | 240 ms
14,464 KB |
testcase_36 | AC | 233 ms
14,464 KB |
testcase_37 | AC | 231 ms
14,464 KB |
testcase_38 | AC | 233 ms
14,464 KB |
testcase_39 | AC | 237 ms
14,464 KB |
testcase_40 | AC | 236 ms
14,336 KB |
testcase_41 | AC | 52 ms
6,816 KB |
testcase_42 | AC | 54 ms
6,820 KB |
testcase_43 | AC | 58 ms
6,816 KB |
testcase_44 | AC | 64 ms
6,816 KB |
testcase_45 | AC | 65 ms
6,820 KB |
testcase_46 | AC | 70 ms
6,816 KB |
testcase_47 | AC | 79 ms
6,816 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; #ifdef LOCAL #include <debug.hpp> #else #define debug(...) #endif template <class S, class T> struct Intervals { static constexpr S INF = numeric_limits<S>::max() / 2; static constexpr S L = -INF, R = INF; // data[l] : 区間 [l, r) に割り当てられた値(r は次の区間の l) map<S, T> data; // 定義域を [L, R) とし,[L, R) = none_val で初期化 Intervals(T none_val = -1) { data[L] = none_val; data[R] = none_val; } // [l, r) = v void set(S l, S r, T v = 1) { l = max(l, L), r = min(r, R); if (l >= r) return; auto it = data.upper_bound(l); auto pit = prev(it); T vR = pit->second; if (pit->first == l) { pit = data.erase(pit); pit = prev(pit); } T vL = pit->second; // 丸ごと上書きされる区間は削除 while (it != data.end()) { if (it->first > r) break; vR = it->second; it = data.erase(it); } if (v != vR) data[r] = vR; if (v != vL) data[l] = v; } // a[i] T get_value(S i) { assert(L <= i && i < R); return prev(data.upper_bound(i))->second; } // i を含む値の等しい極大区間が [l, r) = v としたとき {l, r, v} を返す tuple<S, S, T> get(S i) { assert(L <= i && i < R); auto it = data.upper_bound(i); auto pit = prev(it); return {pit->first, it->first, pit->second}; } // [l, r) を連長圧縮した結果を {左端, 右端, 値} のリストとして返す vector<tuple<S, S, T>> get_all(S l, S r) { l = max(l, L), r = min(r, R); if (l >= r) return vector<tuple<S, S, T>>(); vector<tuple<S, S, T>> res; auto nit = data.upper_bound(l), it = prev(nit); T i = it->first; while (i < r) { T ni = nit->first; res.emplace_back(max(i, l), min(ni, r), it->second); i = ni; it = nit++; } return res; } }; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); int N, Q; cin >> N >> Q; Intervals<int, int> I; while (Q--) { int type; cin >> type; if (type == 1) { int L, R; cin >> L >> R; // [L, R) を 1 にする I.set(L, R, 1); } if (type == 2) { int L, R; cin >> L >> R; // [L, R) を -1 にする I.set(L, R, -1); } if (type == 3) { int u, v; cin >> u >> v; if (u > v) swap(u, v); // (u, v) がつながっているか auto [l, r, val] = I.get(u); // debug(u, v, l, r, val); cout << ((u == v) || (val != -1 && v <= r) ? 1 : 0) << '\n'; } if (type == 4) { int v; cin >> v; // v が含まれる区間幅 auto [l1, r1, val1] = I.get(v - 1); auto [l2, r2, val2] = I.get(v); // debug(v, l, r, val); if (val1 == val2) { cout << (val1 != -1 ? r2 - l1 + 1 : 1) << '\n'; } else if (val1 == 1) { cout << r1 - l1 + 1 << '\n'; } else { cout << r2 - l2 + 1 << '\n'; } } } }