Submission #1122628

#TimeUsernameProblemLanguageResultExecution timeMemory
1122628SharkyPassport (JOI23_passport)C++20
100 / 100
811 ms131660 KiB
#include "bits/stdc++.h"
using namespace std;

#define int long long
const int N = 200008;
const int INF = 1e9;

int n, q, d[4 * N], leaf[N], ll[N], rr[N];
vector<pair<int, int>> g[4 * N];

void ae(int u, int v, int w) {
    g[u].push_back({v, w});
}

struct SegTree {
    int size = 1;
    void init(int n) {
        while (size < n) size *= 2;
    }
    void build(int l, int r, int id) {
        if (l == r) {
            leaf[l] = id;
            return;
        }
        int mid = (l + r) / 2;
        build(l, mid, id * 2);
        build(mid + 1, r, id * 2 + 1);
        ae(id * 2, id, 0);
        ae(id * 2 + 1, id, 0);
    }
    void update(int x, int ql, int qr, int l, int r, int id) {
        if (qr < l || r < ql) return;
        if (ql <= l && r <= qr) {
            if (l != r) ae(id, leaf[x], 1);
            else ae(leaf[l], leaf[x], 1);
            return;
        }
        int mid = (l + r) / 2;
        update(x, ql, qr, l, mid, id * 2);
        update(x, ql, qr, mid + 1, r, id * 2 + 1);
    }
} ST;

vector<int> compute(int s) {
    vector<int> dist(4 * N, INF);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
    pq.push({0, s});
    dist[s] = 0;
    while (!pq.empty()) {
        auto [dd, u] = pq.top();
        pq.pop();
        if (dist[u] != dd) continue;
        for (auto& [v, w] : g[u]) {
            if (dist[u] + w < dist[v]) {
                dist[v] = dist[u] + w;
                pq.push({dist[v], v});
            }
        }
    }
    return dist;
}

int32_t main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n;
    ST.init(n + 1);
    ST.build(1, n, 1);
    for (int i = 1; i <= n; i++) {
        cin >> ll[i] >> rr[i];
        ST.update(i, ll[i], rr[i], 1, n, 1);
    }
    vector<int> d1 = compute(leaf[1]);
    vector<int> dn = compute(leaf[n]);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
    for (int i = 0; i < 4 * N; i++) d[i] = INF;
    for (int i = 1; i <= n; i++) {
        d[leaf[i]] = d1[leaf[i]] + dn[leaf[i]] - 1;
        if (ll[i] == 1 && rr[i] == n) d[leaf[i]] = 1;
        else if (ll[i] == 1) d[leaf[i]] = dn[leaf[i]];
        else if (rr[i] == n) d[leaf[i]] = d1[leaf[i]];
        // cout << "dist; " << d1[leaf[i]] << " " << dn[leaf[i]] << '\n';
        // if (ll[i] == 1 && rr[i] == n) d[leaf[i]] = 1;
        // else if (rr[i] == n) d[leaf[i]]--;
        // else if (ll[i] == 1) d[leaf[i]]--;
        // cout << d[leaf[i]] << " " << i << '\n';
        pq.push({d[leaf[i]], leaf[i]});
    }
    while (!pq.empty()) {
        auto [dd, u] = pq.top();
        pq.pop();
        if (d[u] != dd) continue;
        for (auto& [v, w] : g[u]) {
            if (d[u] + w < d[v]) {
                d[v] = d[u] + w;
                pq.push({d[v], v});
            }
        }
    }
    cin >> q;
    while (q--) {
        int x;
        cin >> x;
        if (d[leaf[x]] >= INF) cout << "-1\n";
        else cout << d[leaf[x]] << '\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...