結果

問題 No.2292 Interval Union Find
ユーザー rniyarniya
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

#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;
}
0