Submission #1275265

#TimeUsernameProblemLanguageResultExecution timeMemory
1275265nguynPassport (JOI23_passport)C++20
100 / 100
161 ms16736 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define F first
#define S second
#define pb push_back
#define pii pair<int, int>

const int N = 2e5 + 5;
const int inf = 1e9;

int d1[N], dn[N], d[N];
int n, q;
int pos[N];
array<int, 3> a[N];
int st[4 * N];
vector<pii> vec[2 * N];

void build(int id, int l, int r) {
    if (l == r) {
        st[id] = a[l][1];
        return;
    }
    int mid = (l + r) / 2;
    build(id * 2, l, mid);
    build(id * 2 + 1, mid + 1, r);
    st[id] = max(st[id * 2], st[id * 2 + 1]);
}

void reset() {
    build(1, 1, n);
}

void get(int id, int l, int r, int x, vector<int> &g) {
    if (x < a[l][0] || x > st[id]) return;
    if (l == r) {
        g.pb(l);
        st[id] = 0;
        return;
    }
    int mid = (l + r) / 2;
    get(id * 2, l, mid, x, g);
    get(id * 2 + 1, mid + 1, r, x, g);
    st[id] = max(st[id * 2], st[id * 2 + 1]);
}

void dijkstra(int s, int (&dist)[N]) {
    deque<pii> q;
    int cur_nodes = 0;
    int cur = 0;
    if (s) {
        for (int i = 1; i <= n; i++) {
            dist[i] = inf;
        }
        dist[s] = 0;
        q.push_back({dist[s], s});
    }
    else {
        for (int i = 1; i <= n; i++) {
            if (dist[i] != inf) {
                cur_nodes++;
                vec[dist[i]].pb({dist[i], i});
            }
        }
    }
    while(!q.empty() || cur_nodes) {
        while(cur_nodes && (q.empty() || cur < q.front().F)) {
            cur++;
            if (!vec[cur].empty()) {
                for (auto it : vec[cur]) {
                    q.push_front(it);
                    cur_nodes--;
                }
            }
        }
        int du = q.front().F;
        int u = q.front().S;
        q.pop_front();

        if (du != dist[u]) continue;

        vector<int> g;
        get(1, 1, n, a[u][2], g);

//        if (!s) cout << a[u][2] << ": ";
        for (int v : g) {
//            if (!s) cout << a[v][2] << ' ';
            if (du + 1 < dist[v]) {
                dist[v] = du + 1;
                q.push_back({dist[v], v});
            }
        }
//        if (!s) cout << '\n';
    }
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i][0] >> a[i][1];
        a[i][2] = i;
    }
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i++) {
        pos[a[i][2]] = i;
    }
    reset();
    dijkstra(pos[1], d1);
    reset();
    dijkstra(pos[n], dn);
    for (int i = 1; i <= n; i++) {
        d[i] = min(d1[i] + dn[i], inf);
        if (d[i] != inf) {
            int x = max(0, d1[i] - 1);
            int y = max(0, dn[i] - 1);
            d[i] = min(d[i], x + y + 1);
        }

    }
    reset();
    dijkstra(0, d);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        int x; cin >> x;
        cout << (d[pos[x]] == inf ? -1 : d[pos[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...