結果

問題 No.2292 Interval Union Find
ユーザー coindarwcoindarw
提出日時 2024-10-01 02:13:20
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 173 ms / 5,000 ms
コード長 4,652 bytes
コンパイル時間 3,151 ms
コンパイル使用メモリ 253,712 KB
実行使用メモリ 12,928 KB
最終ジャッジ日時 2024-10-01 02:13:34
合計ジャッジ時間 11,983 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 3 ms
5,248 KB
testcase_02 AC 3 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 100 ms
5,248 KB
testcase_05 AC 80 ms
5,248 KB
testcase_06 AC 58 ms
5,248 KB
testcase_07 AC 79 ms
5,248 KB
testcase_08 AC 92 ms
5,248 KB
testcase_09 AC 90 ms
5,248 KB
testcase_10 AC 83 ms
5,248 KB
testcase_11 AC 77 ms
5,248 KB
testcase_12 AC 110 ms
5,248 KB
testcase_13 AC 74 ms
5,248 KB
testcase_14 AC 75 ms
5,248 KB
testcase_15 AC 77 ms
5,248 KB
testcase_16 AC 74 ms
5,248 KB
testcase_17 AC 83 ms
5,248 KB
testcase_18 AC 132 ms
12,800 KB
testcase_19 AC 173 ms
12,928 KB
testcase_20 AC 132 ms
12,800 KB
testcase_21 AC 119 ms
8,832 KB
testcase_22 AC 144 ms
8,960 KB
testcase_23 AC 120 ms
8,960 KB
testcase_24 AC 118 ms
8,832 KB
testcase_25 AC 118 ms
8,960 KB
testcase_26 AC 119 ms
8,832 KB
testcase_27 AC 122 ms
8,832 KB
testcase_28 AC 119 ms
8,832 KB
testcase_29 AC 119 ms
8,960 KB
testcase_30 AC 119 ms
8,960 KB
testcase_31 AC 117 ms
8,832 KB
testcase_32 AC 117 ms
8,832 KB
testcase_33 AC 118 ms
8,832 KB
testcase_34 AC 119 ms
8,832 KB
testcase_35 AC 118 ms
8,960 KB
testcase_36 AC 127 ms
8,832 KB
testcase_37 AC 125 ms
8,960 KB
testcase_38 AC 132 ms
8,832 KB
testcase_39 AC 147 ms
8,832 KB
testcase_40 AC 122 ms
8,832 KB
testcase_41 AC 48 ms
5,248 KB
testcase_42 AC 45 ms
5,248 KB
testcase_43 AC 48 ms
5,248 KB
testcase_44 AC 52 ms
5,248 KB
testcase_45 AC 57 ms
5,248 KB
testcase_46 AC 54 ms
5,248 KB
testcase_47 AC 60 ms
5,248 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

template <typename T>
struct Range {
    T l, r;
    Range(T l, T r) : l(l), r(r) {
        if (l > r) l = r = 0ll;
    }
    Range() : Range(0ll, 0ll) {}
    Range operator&(Range b) const {
        T nl = max(l, b.l), nr = min(r, b.r);
        if (nl < nr) return Range(nl, nr);
        else return Range();
    }
    Range operator|(Range b) const {
        if (max(l, b.l) > min(r, b.r)) return Range();
        return Range(min(l, b.l), max(r, b.r));
    }
    bool empty() const { return l == r; }
    bool contains(T x) const { return l <= x && x < r; }
    T count() const { return r - l; }
    bool operator<(const Range& b) const { return (l != b.l) ? l < b.l : r < b.r; }
};
template <typename T>
struct RangeSet {
    set<Range<T>> ranges;
    RangeSet() {}
    int64_t cnt = 0;

    void insert(Range<T> r) {
        if (r.empty()) return;
        auto it = ranges.lower_bound(r);
        if (it != ranges.end() && it->l == r.l && r.r <= it->r) return;
        if (it != ranges.begin()) {
            auto pit = prev(it);
            if (r.r <= pit->r) return;
            if (r.l <= pit->r) {
                r.l = pit->l;
                cnt -= pit->count();
                ranges.erase(pit);
            }
        }
        while (it != ranges.end() && r.r >= it->l) {
            r.r = max(r.r, it->r);
            cnt -= it->count();
            it = ranges.erase(it);
        }
        cnt += r.count();
        ranges.insert(r);
    }
    void erase(Range<T> r) {
        if (r.empty()) return;
        auto it = ranges.lower_bound(r);
        if (it != ranges.end() && it->l == r.l && r.r <= it->r) {
            Range<T> nl = Range(it->l, r.l);
            Range<T> nr = Range(r.r, it->r);
            cnt -= it->count();
            cnt += nl.count() + nr.count();
            ranges.erase(it);
            if (!nl.empty()) ranges.insert(nl);
            if (!nr.empty()) ranges.insert(nr);
            return;
        }
        if (it != ranges.begin()) {
            auto pit = prev(it);
            if (r.r <= pit->r) {
                Range<T> nl = Range(pit->l, r.l);
                Range<T> nr = Range(r.r, pit->r);
                cnt -= pit->count();
                cnt += nl.count() + nr.count();
                ranges.erase(pit);
                if (!nl.empty()) ranges.insert(nl);
                if (!nr.empty()) ranges.insert(nr);
                return;
            }
            if (r.l <= pit->r) {
                Range<T> nl = Range(pit->l, r.l);
                cnt -= pit->count();
                ranges.erase(pit);
                if (!nl.empty()) ranges.insert(nl);
            }
        }
        while (it != ranges.end() && r.r >= it->l) {
            if (it->r <= r.r) {
                cnt -= it->count();
                it = ranges.erase(it);
            } else {
                Range<T> nr = Range(r.r, it->r);
                cnt -= it->count();
                it = ranges.erase(it);
                if (!nr.empty()) ranges.insert(nr);
            }
        }
    }
    Range<T> get(T x) {
        auto it = ranges.lower_bound(Range<T>(x, numeric_limits<T>::max()));
        if (it != ranges.begin()) {
            auto pit = prev(it);
            if (pit->contains(x)) return *pit;
        }
        return Range<T>();
    }
};

template <typename T>
struct RangeSetDisjoint {
    RangeSet<T> rs;
    RangeSetDisjoint() {}
    void insert(Range<T> r) {
        T x = r.l * 2, y = (r.r - 1) * 2;
        Range r2(x, y + 1);
        rs.insert(r2);
    }
    void erase(Range<T> r) {
        T x = r.l * 2, y = (r.r - 1) * 2;
        Range r2(x + 1, y);
        rs.erase(r2);
    }
    Range<T> get(T x) {
        Range<T> r = rs.get(x * 2);
        if (r.empty()) return r;
        return Range<T>(r.l / 2, (r.r + 1) / 2);
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, q;
    cin >> n >> q;

    RangeSetDisjoint<int> rs;

    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int l, r;
            cin >> l >> r;
            rs.insert({l, r + 1});
        } else if (t == 2) {
            int l, r;
            cin >> l >> r;
            rs.erase({l, r + 1});
        } else if (t == 3) {
            int u, v;
            cin >> u >> v;
            if (u == v) {
                cout << 1 << "\n";
                continue;
            }
            auto r = rs.get(u);
            cout << r.contains(v) << "\n";
        } else {
            int v;
            cin >> v;
            auto r = rs.get(v);
            cout << max(1, r.count()) << "\n";
        }
    }
}
0