Submission #1351879

#TimeUsernameProblemLanguageResultExecution timeMemory
1351879azul_safiroEvent Hopping (BOI22_events)C++20
25 / 100
1600 ms589824 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;
int const M = 1e18 + 1e9 + 9;
vector <int> gr;

int merge(int a, int b) {
    return min(a, b);
}

void upd(int l, int r, int v, int p, int val) {
    if (r == l) gr[v] = merge(gr[v], val);
    else {
        int m = (l + r) / 2;
        if (m >= p) upd(l, m, v << 1, p, val);
        else upd(m + 1, r, v << 1 | 1, p, val);

        gr[v] = merge(gr[v << 1], gr[v << 1 | 1]);
    }
}

int get(int l, int r, int v, int ql, int qr) {
    if (r < ql || qr < l) return M;
    if (ql <= l && r <= qr) return gr[v];

    int m = (l + r) / 2;
    return merge(get(l, m, v << 1, ql, qr), get(m + 1, r, v << 1 | 1, ql, qr));
}

void solve(int n, int q) {

    vector <vector <int> > v(n, vector <int> (3));
    for (int i = 0; i < n; i ++) {
        cin >> v[i][1] >> v[i][0];
        v[i][2] = i;
    }
    sort(v.begin(), v.end());

    int gro[n];
    int ans[n];
    vector <vector <int>> v1;
    for (int i = 0; i < n; i ++) {
        int i1 = i, mn = M;
        while (i1 < n && v[i][0] == v[i1][0]) mn = min(mn, v[i1][1]), gro[v[i1][2]] = v1.size(), ans[v[i1][2]] = i1, i1 ++;
        v1.push_back({v[i][0], mn});
        i = i1 - 1;
    }

    int n1 = v1.size();
    int dp[n1][n];
    for (int i = 0; i < n1; i ++) {
        gr.assign(4 * n1, M);
        upd(0, n1 - 1, 1, i, 0);
        for (int j = 0; j < n; j ++) {
            int l = i - 1, r = gro[v[j][2]];
            while (r - l > 1) {
                int m = (l + r) / 2;
                if (v1[m][0] >= v[j][1]) r = m;
                else l = m;
            }
            // cout << i << " " << v[j][2] << " ";
            int mn = get(0, n1 - 1, 1, r, gro[v[j][2]]);
            // cout << mn << "\n";
            if (mn == M) dp[i][j] = -1;
            else dp[i][j] = mn + 1;

            if (dp[i][j] != -1) upd(0, n1 - 1, 1, gro[v[j][2]], dp[i][j]);
        }
    }

    while (q --) {
        int s, e;
        cin >> s >> e;
        s --, e --;
        if (s == e) {
            cout << "0\n";
        } else if (dp[gro[s]][ans[e]] == -1) cout << "impossible\n";
        else cout << dp[gro[s]][ans[e]] << '\n';
    }
    return ;
}

void solve1(int n, int q) {

    vector <vector <int> > v(n, vector <int> (3));
    for (int i = 0; i < n; i ++) {
        cin >> v[i][1] >> v[i][0];
        v[i][2] = i;
    }
    sort(v.begin(), v.end());

    int gr[n];
    int a[n][2];
    vector <vector <int>> v1;
    for (int i = 0; i < n; i ++) {
        int i1 = i, mn = M;
        while (i1 < n && v[i][0] == v[i1][0]) mn = min(mn, v[i1][1]), gr[v[i1][2]] = v1.size(), a[v[i1][2]][0] = v[i1][1], a[v[i1][2]][1] = v[i1][1], i1 ++;
        v1.push_back({v[i][0], mn});
        i = i1 - 1;
    }

    int n1 = v1.size();
    int sp[n1][20], lg[n1 + 1];
    lg[0] = -1;
    for (int i = 1; i <= n1; i ++) lg[i] = lg[i / 2] + 1;

    for (int i = 0; i < n1; i ++) sp[i][0] = v1[i][1];
    for (int j = 1; j < 20; j ++) {
        for (int i = 0; i + (1 << j) - 1 < n1; i ++) {
            sp[i][j] = min(sp[i][j - 1], sp[i + (1 << (j - 1))][j - 1]);
        }
    }

    auto get = [&](int l, int r) {
        int len = r - l + 1, i = lg[len];
        return(min(sp[l][i], sp[r - (1 << i) + 1][i]));
    };

    while (q --) {
        int s, e;
        cin >> s >> e;
        s --, e --;
        int cnt = (s == e ? -1 : 0);
        int l = a[e][0];
        s = gr[s], e = gr[e];

        if (s > e) l = -1;

        while (l > v1[s][0]) {
            cnt ++;
            int lb = s, ub = e;
            while (ub - lb > 1) {
                int m = (ub + lb) / 2;
                if (v1[m][0] < l) lb = m;
                else ub = m;
            }

            int mnl = get(ub, e);
            if (mnl == l) l = -1;
            else l = mnl;
        }

        if (l == -1) cout << "impossible\n";
        else cout << cnt + 1 << '\n';
    }

    return ;
}

signed main() {
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int t = 1;
    // cin >> t;
    while (t --) {
        int n, q;
        cin >> n >> q;
        if ((n * q) <= 1e8) solve1(n, q);
        else solve(n, q);
    }
    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...