제출 #1092958

#제출 시각아이디문제언어결과실행 시간메모리
1092958ortsacRailway Trip 2 (JOI22_ho_t4)C++17
100 / 100
1648 ms96984 KiB
#include <bits/stdc++.h>

using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;

struct Node {
    int mi = INF, mx = -INF;
};

Node join(const Node& a, const Node& b) {
    Node ans;
    ans.mi = min(a.mi, b.mi);
    ans.mx = max(a.mx, b.mx);
    return ans;
}

Node empt;

struct SegTree {
    Node seg[4*MAXN];
    int lazyMi[4*MAXN];
    int lazyMx[4*MAXN];
    void build(int node, int l, int r) {
        lazyMx[node] = -INF;
        lazyMi[node] = INF;
        if (l == r) {
            seg[node].mi = seg[node].mx = l;
            return;
        }
        int m = (l + r)/2;
        build(2*node, l, m);
        build(2*node + 1, m + 1, r);
        seg[node] = join(seg[2*node], seg[2*node + 1]);
    }
    void unlazy(int node, int l, int r) {
        // do lazymi
        if (lazyMi[node] != INF) {
            seg[node].mi = min(seg[node].mi, lazyMi[node]);
            if (l < r) {
                lazyMi[2*node] = min(lazyMi[2*node], lazyMi[node]);
                lazyMi[2*node + 1] = min(lazyMi[2*node + 1], lazyMi[node]);
            }
            lazyMi[node] = INF;
        }
        if (lazyMx[node] != (-INF)) {
            seg[node].mx = max(seg[node].mx, lazyMx[node]);
            if (l < r) {
                lazyMx[2*node] = max(lazyMx[2*node], lazyMx[node]);
                lazyMx[2*node + 1] = max(lazyMx[2*node + 1], lazyMx[node]);
            }
            lazyMx[node] = (-INF);
        }
    }
    void update(int node, int l, int r, int tl, int tr, int val) {
        unlazy(node, l, r);
        if ((r < tl) || (tr < l)) return;
        if ((tl <= l) && (r <= tr)) {
            lazyMi[node] = min(lazyMi[node], val);
            lazyMx[node] = max(lazyMx[node], val);
            unlazy(node, l, r);
            return;
        }
        int m = (l+r)/2;
        update(2*node, l, m, tl, tr, val);
        update(2*node + 1, m + 1, r, tl, tr, val);
        seg[node] = join(seg[2*node], seg[2*node + 1]);
    }
    Node query(int node, int l, int r, int tl, int tr) {
        unlazy(node, l, r);
        if ((r < tl) || (tr < l)) return empt;
        if ((tl <= l) && (r <= tr)) return seg[node];
        int m = (l+r)/2;
        return join(query(2*node, l, m, tl, tr), query(2*node + 1, m + 1, r, tl, tr));
    }
};

bool inRange(int a, int l, int r) {
    return ((l <= a) && (a <= r));
}

const int MAXLOG = 18;
SegTree layer[MAXLOG];

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, k, m, q;
    cin >> n >> k >> m;
    layer[0].build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        if (a < b) {
            int upTo = min(a + k - 1, b - 1);
            layer[0].update(1, 1, n, a, upTo, b);
        } else {
            int upTo = max(a - k + 1, b + 1);
            layer[0].update(1, 1, n, upTo, a, b);
        }
    }
    for (int l = 1; l < MAXLOG; l++) {
        layer[l].build(1, 1, n);
        for (int i = 1; i <= n; i++) {
            Node r = layer[l - 1].query(1, 1, n, i, i);
            Node novo = layer[l - 1].query(1, 1, n, r.mi, r.mx);
            layer[l].update(1, 1, n, i, i, novo.mi);
            layer[l].update(1, 1, n, i, i, novo.mx);
        }
    }
    cin >> q;
    while (q--) {
        int s, t;
        cin >> s >> t;
        // check if its -1
        Node ult = layer[MAXLOG - 1].query(1, 1, n, s, s);
        if (!inRange(t, ult.mi, ult.mx)) {
            cout << "-1\n";
            continue;
        }
        int mult = 1;
        for (int i = 0; i < (MAXLOG - 1); i++) {
            mult <<= 1;
        }
        int minAns = INF;
        int curr = 0;
        int l = s, r = s;
        for (int i = MAXLOG - 1; i >= 0; i--) {
            Node can = layer[i].query(1, 1, n, l, r);
            if (!inRange(t, can.mi, can.mx)) {
                l = can.mi;
                r = can.mx;
                curr += mult;
            } else {
                minAns = min(minAns, curr + mult);
            }
            mult >>= 1;
        }
        cout << minAns << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...