Submission #1187271

#TimeUsernameProblemLanguageResultExecution timeMemory
1187271qwushaEvent Hopping (BOI22_events)C++20
0 / 100
624 ms119212 KiB
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define int long long
typedef long long ll;
typedef long double ld;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
int inf = 1e15;

int n;

vector<int> dtl, dtr;
vector<vector<int>> gl;
vector<set<vector<int>>> gr;
vector<int> col;
int curco = 0;

void dfsl(int v, int p = -1, int d=0) {
    col[v] = curco;
    dtl[v] = d;
    for (auto u : gl[v]) {
        if (u != p) {
            dfsl(u, v, d + 1);
        }
    }
}
void dfsr(int v, int p = -1, int d=0) {
    dtr[v] = d;
    for (auto u : gr[v]) {
        if (u[2] != p) {
            dfsr(u[2], v, d + 1);
        }
    }
}


bool cmp(vector<int> a, vector<int> b) {
    return (a[1] < b[1]);
}

signed main() {
    int  q;
    cin >> n >> q;
    gl.resize(n);
    gr.resize(n);
    dtr.resize(n);
    dtl.resize(n);
    col.resize(n);
    vector<vector<int>> a(n, vector<int>(3));
    for (int i = 0; i < n; i++) {
        cin >> a[i][0] >> a[i][1];
        a[i][2] = i;
    }
    auto b = a;
    auto ini = a;
    sort(a.begin(), a.end());
    sort(b.begin(), b.end(), cmp);
    vector<int> coolle, coolri;
    vector<vector<int>> to_rig, to_left;
    int last = -1;
    int cur = 0;
    while (cur < n) {
        int val = a[cur][0];
        int maxi = -1;
        int mind = -1;
        while(cur < n && a[cur][0] == val) {
            if (maxi < a[cur][1]) {
                maxi = a[cur][1];
                mind= cur;
            }
            cur++;
        }
        if (maxi > last) {
            to_rig.push_back(a[mind]);
            last = maxi;
        }
    }
    cur = n - 1;
    last = inf;
    while (cur >= 0) {
        int val = b[cur][1];
        int mini = inf, mind = -1;
        while (cur >= 0 && b[cur][1] == val) {
            if (mini > b[cur][0]) {
                mini = b[cur][0];
                mind = cur;
            }
            cur--;
        }
        if (mini < last) {
            last = mini;
            to_left.push_back(b[mind]);
        }
    }
    vector<int> par_to_lef(n), par_to_rig(n);
    for (int i = 0; i < n; i++) {
        par_to_lef[i] = i;
        par_to_rig[i] = i;
    }
    vector<set<vector<int>>> went_to(n);
    for (int i = 0; i < n; i++) {
        int ind = a[i][2];
        int end = a[i][1];
        int l = 0, r = to_rig.size();
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (to_rig[mid][0] <= end) {
                l = mid;
            } else {
                r = mid;
            }
        }
        if (to_rig[l][2] == ind) {
            coolri.push_back(ind);
        } else {
            int pare = to_rig[l][2];
            par_to_rig[ind] = pare;
            gr[ind].insert(ini[pare]);
            gr[pare].insert(ini[ind]);
            went_to[pare].insert(ini[ind]);
            if (ini[ind][1] == ini[pare][1]) {
                went_to[ind].insert(ini[pare]);
            }
        }
    }
    for (int i = n - 1; i >= 0; i--) {
        if (went_to[i].size() == 0) {
            coolle.push_back(i);
            continue;
        }
        auto vec = *went_to[i].begin();
        if (vec[0] > ini[i][0] || (vec[0] == ini[i][0] && vec[1] > ini[i][1])) {
            coolle.push_back(i);
            continue;
        }
        par_to_lef[i] = vec[2];
        gl[i].push_back(vec[2]);
        gl[vec[2]].push_back(i);
    }
    curco = 0;
    for (auto el : coolle) {
        dfsl(el);
        curco++;
    }
    for (auto el : coolri) {
        dfsr(el);
    }
    int logn = 3, vallog = 1;
    while (vallog < n) {
        vallog *= 2;
        logn++;
    }
    vector<vector<int>> upstl(logn, vector<int>(n)), upstr(logn, vector<int>(n));
    for (int i = 0; i < n; i++) {
        upstl[0][i] = par_to_lef[i];
        upstr[0][i] = par_to_rig[i];
    }
    for (int j = 1; j < logn; j++) {
        for (int i = 0; i < n; i++) {
            upstl[j][i] = upstl[j - 1][upstl[j - 1][i]];
            upstr[j][i] = upstr[j - 1][upstr[j - 1][i]];
        }
    }
    for (int qw = 0; qw < q; qw++) {
        int s, e;
        cin >> s >> e;
        s--;
        e--;
        if (col[s] != col[e] || ini[s][0] >= ini[e][1]) {
            cout << "impossible" << '\n';
            continue;
        }
        if (s == e) {
            cout << 0 << '\n';
            continue;
        }
        int curv = s;
        for (int i = logn - 1; i >= 0; i--) {
            if (ini[upstr[i][curv]][1] < ini[e][0])
                curv = upstr[i][curv];
        }
        int curu = e;
        for (int i = logn - 1; i >= 0; i--) {
            if (ini[upstl[i][curu]][0] > ini[curv][1]) {
                curu = upstl[i][curu];
            }
        }
        int nv = curv;
        if (ini[curv][1] < ini[curu][0])
            nv = par_to_rig[curv];
        if (ini[nv][1] < ini[curu][0] || ini[nv][1] > ini[curu][1]) {
            nv = curv;
            int nu = par_to_lef[curu];
            if (ini[nv][1] < ini[nu][0] || ini[nv][1] > ini[nu][1]) {
                cout << "impossible" << '\n';
            } else {
                cout << dtr[s] - dtr[nv] + dtl[e] - dtl[nu] + 1 << '\n';
            }
        } else {
            cout << dtr[s] - dtr[nv] + dtl[e] - dtl[curu] + 1 << '\n';
        }
    }
}
#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...