Submission #1290130

#TimeUsernameProblemLanguageResultExecution timeMemory
1290130nqcEvent Hopping (BOI22_events)C++20
100 / 100
230 ms17236 KiB
#include<bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pli pair<ll, int>
#define debug(x) cout << #x << " = " << x << '\n'
#define all(a) a.begin(), a.end()
#define SZ(a) (int)(a).size()

const int N = 1e5 + 5;
const int mod = 1e9 + 7;
const ll inf64 = 3e18;
const int inf32 = 2e9 + 5;

struct SegmentTree {
    int n;
    vector<pii> node;

    SegmentTree() {}
    SegmentTree(int n) : n(n), node(n << 2, make_pair(inf32, 0)) {}

    void upd(int id, int l, int r, int i, pii p) {
        if(l == r) {
            node[id] = min(node[id], p);
            return;
        }

        int mid = (l + r) >> 1;
        if(i <= mid) upd(id << 1, l, mid, i, p);
        else upd(id << 1 | 1, mid + 1, r, i, p);

        node[id] = min(node[id << 1], node[id << 1 | 1]);
    }
    void upd(int i, pii p) { upd(1, 1, n, i, p); }

    pii get(int id, int l, int r, int x, int y) {
        if(x <= l && r <= y) return node[id];

        int mid = (l + r) >> 1;
        if(mid < x) return get(id << 1 | 1, mid + 1, r, x, y);
        if(mid + 1 > y) return get(id << 1, l, mid, x, y);
        return min(get(id << 1, l, mid, x, y), get(id << 1 | 1, mid + 1, r, x, y));
    }
    pii get(int l, int r) { return get(1, 1, n, l, r); }
};

int n, q, pos[N];
struct Event { int l, r, idx; } a[N];

const int LG = 18;
int jump[LG][N];

int Jumping(int s, int d) {
    if(d == 0) return s;
    for(int k = 0; (1 << k) <= d; k++) 
        if(d >> k & 1) s = jump[k][s];
    return s;
}

void solve() {
    cin >> n >> q;
    vector<int> cprs;
    for(int i = 1; i <= n; i++) {
        cin >> a[i].l >> a[i].r;
        a[i].idx = i;
        cprs.push_back(a[i].l);
        cprs.push_back(a[i].r);
    }

    sort(all(cprs)); cprs.erase(unique(all(cprs)), cprs.end());
    for(int i = 1; i <= n; i++) {
        a[i].l = lower_bound(all(cprs), a[i].l) - cprs.begin() + 1;
        a[i].r = lower_bound(all(cprs), a[i].r) - cprs.begin() + 1;
    }

    sort(a + 1, a + 1 + n, [](Event x, Event y) {
        if(x.r != y.r) return x.r < y.r;
        else return x.l < y.l;
    });

    for(int i = 1; i <= n; i++) 
        pos[a[i].idx] = i;


    SegmentTree seg(SZ(cprs));
    jump[0][0] = 0;
    for(int i = 1; i <= n; i++) {
        int p = seg.get(a[i].l, a[i].r).se;
        jump[0][i] = p;
        seg.upd(a[i].r, make_pair(a[i].l, i));
    }
    for(int k = 1; k < LG; k++) {
        for(int i = n; i >= 0; i--) 
            jump[k][i] = jump[k - 1][jump[k - 1][i]];
    }

    
    while(q--) {
        int S, E; cin >> S >> E;
        S = pos[S], E = pos[E];

        if(S == E) {
            cout << "0\n";
            continue;
        }
        if(a[S].r > a[E].r) {
            cout << "impossible\n";
            continue;
        }
        if(a[S].r >= a[E].l) {
            cout << "1\n";
            continue;
        }

        int le = 1, ri = n, d = 0;
        while(le <= ri) {
            int mid = (le + ri) >> 1;
            int p = Jumping(E, mid);
            if(p == 0 || a[p].l <= a[S].r) ri = mid - 1;
            else d = mid, le = mid + 1;
        }

        int i = Jumping(E, d + 1);
        if(i != 0 && a[i].l <= a[S].r) cout << d + 2 << '\n';
        else cout << "impossible\n";
    }
}

int main() {
    auto start = chrono::steady_clock::now();

    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    if(fopen("input.txt", "r")) {
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    }
    int test = 1; 
    // cin >> test;
    while(test--) solve();
    
    chrono::duration<double> elapsed {chrono::steady_clock::now() - start};
    cerr << "\n>> Runtime: " << elapsed.count() << "s\n";
}

Compilation message (stderr)

events.cpp: In function 'int main()':
events.cpp:139:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  139 |         freopen("input.txt", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
events.cpp:140:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  140 |         freopen("output.txt", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...