Submission #1344053

#TimeUsernameProblemLanguageResultExecution timeMemory
1344053BlockOGEvent Hopping (BOI22_events)C++20
100 / 100
212 ms15964 KiB
#include <bits/stdc++.h>

// mrrrowwww meeowwwww :3
// go play vivid/stasis! !! !!! https://vividstasis.gay

#define fo(i, a, b) for (auto i = (a); i < (b); i++)
#define of(i, a, b) for (auto i = (b); i-- > (a);)
#define f first
#define s second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define be(a) a.begin(), a.end()
using namespace std;

int ____init = []{
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    return 0;
}();

template <typename Node>
struct SegTree {
    int n, N;
    vector<Node> values;

    SegTree(const vector<Node> &values) {
        n = values.size();
        N = 1 << (32 - __builtin_clz(n - 1));

        this->values.resize(N * 2);
        fo(i, 0, n) this->values[N + i] = values[i];
        of(i, 1, N) this->values[i] = this->values[i * 2] + this->values[i * 2 + 1];
    }

    Node get(int l, int r) {
        Node res = values[0];
        for (l = N + max(0, l), r = N + min(r, n); l < r; l /= 2, r /= 2) {
            if (l & 1) res = res + values[l++];
            if (r & 1) res = res + values[--r];
        }

        return res;
    }

    void set(int i, int v) {
        if (i < 0 || i >= n) return;
        values[i += N] = v;
        for (i /= 2; i > 0; i /= 2) values[i] = values[i * 2] + values[i * 2 + 1];
    }
};

struct BinaryLifting {
    int N;
    vector<vector<int>> parents;

    BinaryLifting(int n) {
        parents.resize(n);

        N = 32 - __builtin_clz(n - 1);
        fo(i, 0, n) parents[i].resize(N), parents[i][0] = i;
    }

    void set(int i, int p) {
        parents[i][0] = p;
    }

    void preprocess() {
        fo(i, 1, N) {
            for (vector<int> &p : parents)
                p[i] = parents[p[i - 1]][i - 1];
        }
    }

    int jump(int i, int c) {
        fo(j, 0, N) if (c & (1 << j)) i = parents[i][j];
        return i;
    }

    template <typename F>
    pair<int, int> search_jump(int i, F &&c) {
        int jumped = 0;
        of(j, 0, N) if (c(parents[i][j])) i = parents[i][j], jumped += 1 << j;
        return { i, jumped };
    }
};

struct Event {
    int start, end, i;
    Event() : start(INT_MAX) {}
};

Event operator+(const Event &l, const Event &r) {
    return l.start <= r.start ? l : r;
}

int main() {
    int n, q; cin >> n >> q;
    vector<Event> events(n);
    fo(i, 0, n) cin >> events[i].start >> events[i].end, events[i].i = i;
    sort(be(events), [](Event a, Event b) { return a.end < b.end; });

    SegTree<Event> segtree(events);
    BinaryLifting binlift(n);
    fo(i, 0, n) {
        int l = lb(be(events), events[i], [](Event a, Event b) { return a.end < b.start; }) - events.begin();
        int r = ub(be(events), events[i], [](Event a, Event b) { return a.end < b.end; }) - events.begin();
        binlift.set(events[i].i, segtree.get(l, r).i);
    }
    binlift.preprocess();

    sort(be(events), [](Event a, Event b) { return a.i < b.i; });
    while (q--) {
        int s, e; cin >> s >> e; s--, e--;
        if (s == e) cout << 0 << endl;
        else {
            auto [i, c] = binlift.search_jump(e, [&](int i) { return events[s].end < events[i].start; });
            if (events[s].end < events[i].start)
                i = binlift.jump(i, 1), c++;

            if (events[i].start <= events[s].end && events[s].end <= events[i].end)
                cout << c + 1 << endl;
            else
                cout << "impossible" << endl;
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...