Submission #597493

#TimeUsernameProblemLanguageResultExecution timeMemory
597493yanndevEvent Hopping (BOI22_events)C++17
100 / 100
219 ms30264 KiB
    #include <bits/stdc++.h>
    #define int long long
    #define fi first
    #define se second
    using namespace std;

    struct Inter {
        int rl;
        int rr;
        int id;
        bool operator<(const Inter& other) const {
            if (rr != other.rr)
                return rr < other.rr;
            if (rl != other.rl)
                return rl < other.rl;
            return id < other.id;
        }
    };

    const int MX_N = 1e5 + 42;
    const int TREE_SIZE = (int)1 << 19;

    int rl[MX_N];
    int rr[MX_N];
    int jump[20][MX_N];
    int tree[2 * TREE_SIZE + 42];

    void insert(int idx, int val, bool force = false) {
        idx += TREE_SIZE;
        if ((force) || (rl[val] < rl[tree[idx]]))
            tree[idx] = val;
        for (int i = idx / 2; i > 0; i /= 2) {
            if (rl[tree[2 * i]] < rl[tree[2 * i + 1]])
                tree[i] = tree[2 * i];
            else
                tree[i] = tree[2 * i + 1];
        }
    }

    int query(int left, int right) {
        left += TREE_SIZE;
        right += TREE_SIZE;

        int mnVal = 1e9;
        int id = -1;
        while (left <= right) {
            if (left % 2 == 1) {
                int newId = tree[left];
                if (rl[newId] < mnVal) {
                    mnVal = rl[newId];
                    id = newId;
                }
                left++;
            }

            if (right % 2 == 0) {
                int newId = tree[right];
                if (rl[newId] < mnVal) {
                    mnVal = rl[newId];
                    id = newId;
                }
                right--;
            }

            left /= 2;
            right /= 2;
        }

        return id;
    }

    signed main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        
        int n, q;
        cin >> n >> q;

        vector<Inter> ranges {};
        vector<int> vals {};

        for (int i = 0; i < n; i++) {
            cin >> rl[i] >> rr[i];
            vals.push_back(rl[i]);
            vals.push_back(rr[i]);
        }

        sort(vals.begin(), vals.end());
        vals.resize(unique(vals.begin(), vals.end()) - vals.begin());
        
        for (int i = 0; i < n; i++) {
            rl[i] = lower_bound(vals.begin(), vals.end(), rl[i]) - vals.begin();
            rr[i] = lower_bound(vals.begin(), vals.end(), rr[i]) - vals.begin();
            ranges.push_back({rl[i], rr[i], i});
        }

        rl[n] = rr[n] = 1e9 + 42;
        for (int i = 0; i < (int)vals.size(); i++)
            insert(i, n, true);

        sort(ranges.begin(), ranges.end());
        for (int i = 0; i < n; i++) {
            //cout << "doing range " << ranges[i].id << ' ' << ranges[i].rl << ' ' << ranges[i].rr << '\n';
            jump[0][ranges[i].id] = query(ranges[i].rl, ranges[i].rr);
            //cout << "query is " << jump[0][ranges[i].id] << '\n';
            if (jump[0][ranges[i].id] == -1)
                jump[0][ranges[i].id] = ranges[i].id;

            //cout << "inserting at " << ranges[i].rr << '\n';
            insert(ranges[i].rr, ranges[i].id);
            //cout << "val at pos " << query(ranges[i].rr, ranges[i].rr) << '\n';
        }
        
        for (int i = 1; i <= 19; i++)
            for (int j = 0; j < n; j++)
                jump[i][j] = jump[i - 1][jump[i - 1][j]];

        for (int i = 0; i < q; i++) {
            int s, e;
            cin >> s >> e;
            s--, e--;

            if (s == e) {
                cout << "0\n";
                continue;
            }

            if (rl[e] <= rr[s] && rr[s] <= rr[e]) {
                cout << "1\n";
                continue;
            }

            if (rl[s] > rl[e]) {
                cout << "impossible\n";
                continue;
            }

            int ans = 0;

            //cout << "start has " << rl[s] << ' ' << rr[s] << '\n';
            //cout << "bef jump left is " << rl[e] << " right is " << rr[e] << '\n';

            for (int bit = 19; bit >= 0; bit--) {
                int nxt = jump[bit][e];
                if (rl[nxt] > rr[s]) {
                    //cout << "nxt has " << rl[nxt] << ' ' << rr[nxt] << '\n';
                    //cout << "jumping of " << (1 << bit) << '\n';
                    ans += (1 << bit);
                    e = nxt;
                }
            }

            //cout << "preans " << ans << '\n';
            //cout << "bef end left is " << rl[e] << " right is " << rr[e] << '\n';

            ans++;
            e = jump[0][e];
            //cout << "last jump left is " << rl[e] << " right is " << rr[e] << '\n';
            if (rl[e] <= rr[s] && rr[s] <= rr[e]) {
                cout << ans + 1 << '\n';
            } else {
                cout << "impossible\n";
            }
        }
    }

    /*

    7 1
    1 2
    3 4
    1 5
    6 7
    5 10
    10 20
    15 20
    1 6

    */
#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...