제출 #1370380

#제출 시각아이디문제언어결과실행 시간메모리
1370380pirmyratgPassport (JOI23_passport)C++20
100 / 100
485 ms123472 KiB
#include "bits/stdc++.h"

using namespace std;

#define int long long

const int N = 2e5 + 10;
const int INF = 1e18;

struct segtree {
    int size = 1;
    vector<vector<pair<int, int>>> adj;
    vector<int> leaf_node;
    void init(int n) {
        while (size < n) size <<= 1;
        adj.assign(2 * size, {});
        leaf_node.assign(size + 1, 0);
        build(0, 0, size);
    }
    void build(int x, int lx, int rx) {
        if (rx - lx == 1) {
            leaf_node[lx + 1] = x;
            return;
        }
        int m = (lx + rx) >> 1;
        build(2 * x + 1, lx, m);
        build(2 * x + 2, m, rx);
        adj[2 * x + 1].push_back({x, 0});
        adj[2 * x + 2].push_back({x, 0});
    }
    void add_edge(int l, int r, int target, int v, int x, int lx, int rx) {
        if (lx >= r || l >= rx) return;
        if (lx >= l && rx <= r) {
            adj[x].push_back({target, v});
            return;
        }
        int m = (lx + rx) >> 1;
        add_edge(l, r, target, v, 2 * x + 1, lx, m);
        add_edge(l, r, target, v, 2 * x + 2, m, rx);
    }
    void add_edge(int l, int r, int target, int v) {
        if (l > r) 
        	return;
        add_edge(l - 1, r, target, v, 0, 0, size);
    }
};
int d[8 * N][3];
void bfs(int type, int start, segtree &st) {
    for (int i = 0; i < 2 * st.size; i++) 
    	d[i][type] = INF;
    deque<int> dq;
    d[start][type] = 0;
    dq.push_front(start);
    while (!dq.empty()) {
        int u = dq.front();
        dq.pop_front();
        for (auto &[v, w] : st.adj[u]) {
            if (d[v][type] > d[u][type] + w) {
                d[v][type] = d[u][type] + w;
                if (w == 0) dq.push_front(v);
                else dq.push_back(v);
            }
        }
    }
}
void dijkstra(int n, segtree &st) {
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    for (int i = 0; i < 2 * st.size; i++) 
    	d[i][2] = INF;
    for (int i = 1; i <= n; i++) {
        int u = st.leaf_node[i];
        if (d[u][0] >= INF || d[u][1] >= INF) continue;
        d[u][2] = d[u][0] + d[u][1] - (i != 1 && i != n);
        pq.push({d[u][2], u});
    }
    while (!pq.empty()) {
        auto [c, u] = pq.top();
        pq.pop();
        if (c > d[u][2]) continue;
        for (auto &[v, w] : st.adj[u]) {
            if (d[v][2] > d[u][2] + w) {
                d[v][2] = d[u][2] + w;
                pq.push({d[v][2], v});
            }
        }
    }
}
int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    if (!(cin >> n)) return 0;
    segtree st;
    st.init(n);
    for (int i = 1; i <= n; i++) {
        int l, r;
        cin >> l >> r;
        st.add_edge(l, r, st.leaf_node[i], 1);
    }
    bfs(0, st.leaf_node[1], st);
    bfs(1, st.leaf_node[n], st);
    dijkstra(n, st);
    int q;
    cin >> q;
    while (q--) {
        int x;
        cin >> x;
        int res = d[st.leaf_node[x]][2];
        if (res >= INF / 2) 
        	cout << -1 << "\n";
        else 
        	cout << res << "\n";
    }
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…