제출 #959607

#제출 시각아이디문제언어결과실행 시간메모리
959607TAhmed33Passport (JOI23_passport)C++98
100 / 100
768 ms100380 KiB
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 25;
const int inf = MAXN << 4;
#define mid ((l + r) >> 1)
#define tl (node + 1)
#define tr (node + 2 * (mid - l + 1))
int cnt;
vector <pair <int, int>> radj[MAXN];
void add_edge (int x, int y) {
    radj[x].push_back({y, 0});
}
struct SegmentTree {
    int tree[MAXN << 1];
    int init (int l, int r, int node) {
        if (l == r) return tree[node] = l;
        int x = init(l, mid, tl), y = init(mid + 1, r, tr);
        tree[node] = ++cnt;
        add_edge(x, tree[node]); add_edge(y, tree[node]);
        return tree[node];
    }
    void update (int l, int r, int a, int b, int c, int node) {
        if (l > b || r < a) return;
        if (l >= a && r <= b) {
            add_edge(tree[node], c);
            return;
        }
        update(l, mid, a, b, c, tl); update(mid + 1, r, a, b, c, tr);
    }
} cur;
int n, q;
int dist1[MAXN], dist2[MAXN], dist3[MAXN];
int main () {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n; cnt = n;
    cur.init(1, n, 1);
    for (int i = 1; i <= n; i++) {
        int l, r; cin >> l >> r;
        ++cnt;
        radj[cnt].push_back({i, 1});
        cur.update(1, n, l, r, cnt, 1);
    }
    for (int i = 1; i <= cnt; i++) dist1[i] = dist2[i] = inf;
    priority_queue <pair <int, int>, vector <pair <int, int>>, greater <>> cur;
    cur.push({0, 1}); dist1[1] = 0;
    while (!cur.empty()) {
        auto k = cur.top();
        cur.pop();
        if (k.first > dist1[k.second]) continue;
        for (auto j : radj[k.second]) {
            if (k.first + j.second < dist1[j.first]) {
                dist1[j.first] = k.first + j.second;
                cur.push({dist1[j.first], j.first});
            }
        }
    }
    cur.push({0, n}); dist2[n] = 0;
    while (!cur.empty()) {
        auto k = cur.top();
        cur.pop();
        if (k.first > dist2[k.second]) continue;
        for (auto j : radj[k.second]) {
            if (k.first + j.second < dist2[j.first]) {
                dist2[j.first] = k.first + j.second;
                cur.push({dist2[j.first], j.first});
            }
        }
    }
    for (int i = 1; i <= cnt; i++) {
        dist3[i] = dist1[i] + dist2[i];
        cur.push({dist3[i], i});
    }
    while (!cur.empty()) {
        auto k = cur.top();
        cur.pop();
        if (k.first > dist3[k.second]) continue;
        for (auto j : radj[k.second]) {
            if (k.first + j.second < dist3[j.first]) {
                dist3[j.first] = k.first + j.second;
                cur.push({dist3[j.first], j.first});
            }
        }
    }
    for (int i = 1; i <= cnt; i++) if (dist3[i] > n) dist3[i] = -1;
    cin >> q;
    while (q--) {
        int x; cin >> x;
        cout << dist3[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...