Submission #1342143

#TimeUsernameProblemLanguageResultExecution timeMemory
1342143po_rag526Event Hopping (BOI22_events)C++20
30 / 100
176 ms28672 KiB
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <tuple>
#include <cmath>
#include <limits>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <numeric>
#include <functional>
#include <iostream>
#include <iomanip>
#include <random>

using namespace std;

struct FenwickTree {
    int n;
    vector<int> tree;
    FenwickTree(int n) : n(n), tree(n + 2, 0) {}
    
    void add(int i, int delta) {
        for (; i <= n; i += (i & -i)) tree[i] += delta;
    }
    
    int query(int i) {
        int sum = 0;
        for (; i > 0; i -= (i & -i)) sum += tree[i];
        return sum;
    }
};

int main() {
    ios::sync_with_stdio(0); cin.tie(0);

    int N, Q;
    cin >> N >> Q;

    vector<int> S(N + 1);
    vector<int> E(N + 1);
    
    vector<vector<int>> events(N, vector<int>(3)); 
    for (int i = 1; i <= N; i++) {
        cin >> S[i] >> E[i];
        events[i - 1] = {S[i], E[i], i};
    }
    sort(events.begin(), events.end());

    vector<int> S_vals(N), prefix_max_id(N);
    int cur_max_E = -1, cur_max_id = -1;

    for (int i = 0; i < N; i++) {
        S_vals[i] = events[i][0];
        if (events[i][1] > cur_max_E) {
            cur_max_E = events[i][1];
            cur_max_id = events[i][2];
        }
        prefix_max_id[i] = cur_max_id;
    }

    vector<int> next_opt(N + 1);
    for (int i = 1; i <= N; i++) {
        auto it = upper_bound(S_vals.begin(), S_vals.end(), E[i]);
        if (it == S_vals.begin()) {
            next_opt[i] = i; 
        } else {
            int idx = distance(S_vals.begin(), it) - 1;
            next_opt[i] = prefix_max_id[idx];
        }
    }

    vector<vector<int>> up(N + 1, vector<int>(20));
    for (int i = 1; i <= N; i++) up[i][0] = next_opt[i];

    for (int j = 1; j < 20; j++) {
        for (int i = 1; i <= N; i++) {
            up[i][j] = up[up[i][j - 1]][j - 1];
        }
    }

    vector<int> ans(Q, -1);
    vector<int> comp_vals;
    
    vector<vector<int>> pending; 
    for (int i = 0; i < Q; i++) {
        int s, e;
        cin >> s >> e;

        if (s == e) {
            ans[i] = 0;
            continue;
        }

        int S_e = S[e];
        int E_e = E[e];
        int E_s = E[s];

        if (E_s >= S_e && E_s <= E_e) {
            ans[i] = 1;
            continue;
        }
        if (E_s > E_e) {
            ans[i] = -1;
            continue;
        }

        int u = s;
        int jumps = 0;
        for (int j = 19; j >= 0; j--) {
            int nxt = up[u][j];
            if (E[nxt] < S_e) {
                u = nxt;
                jumps += (1 << j);
            }
        }

        int v = up[u][0]; 
        if (E[v] < S_e) {
            ans[i] = -1;
        } else if (E[v] <= E_e) {
            ans[i] = jumps + 2;
        } else {
            pending.push_back({E[u], S_e, E_e, jumps + 2, i});
            comp_vals.push_back(S_e);
            comp_vals.push_back(E_e);
        }
    }

    for (int i = 1; i <= N; i++) comp_vals.push_back(E[i]);
    sort(comp_vals.begin(), comp_vals.end());
    comp_vals.erase(unique(comp_vals.begin(), comp_vals.end()), comp_vals.end());

    auto get_idx = [&](int val) {
        return distance(comp_vals.begin(), lower_bound(comp_vals.begin(), comp_vals.end(), val)) + 1;
    };

    sort(pending.begin(), pending.end());

    FenwickTree bit(comp_vals.size());
    int ptr = 0;

    for (auto& pq : pending) {
        int E_u = pq[0];
        int S_e = pq[1];
        int E_e = pq[2];
        int final_jumps = pq[3];
        int q_id = pq[4];

        while (ptr < N && events[ptr][0] <= E_u) {
            bit.add(get_idx(events[ptr][1]), 1);
            ptr++;
        }
        
        int cnt = bit.query(get_idx(E_e)) - bit.query(get_idx(S_e) - 1);
        if (cnt > 0) {
            ans[q_id] = final_jumps;
        } else {
            ans[q_id] = -1;
        }
    }

    for (int i = 0; i < Q; i++) {
        if (ans[i] == -1) cout << "impossible" << endl;
        else cout << ans[i] << endl;
    }

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