Submission #1245509

#TimeUsernameProblemLanguageResultExecution timeMemory
1245509RecursiveCoGift Exchange (JOI24_ho_t4)C++20
100 / 100
1786 ms108636 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define in(i) cin >> i
#define out(o) cout << o

// vector<int>

vector<int> tree;

void upd(int v, int l, int r, int i, int x) {
    if (l == r) {
        tree[v] = x;
    } else {
        int middle = (l + r) / 2;
        if (i <= middle) upd(2 * v, l, middle, i, x);
        else upd(2 * v + 1, middle + 1, r, i, x);
        tree[v] = max(tree[2 * v], tree[2 * v + 1]);
    }
}

int query(int v, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return tree[v];
    if (qr < l || r < ql) return -1e9;
    int middle = (l + r) / 2;
    int left = query(2 * v, l, middle, ql, qr);
    int right = query(2 * v + 1, middle + 1, r, ql, qr);
    return max(left, right);
}

int base;
int f(int r, int l, int i) {
    return r * base * base + l * base + i;
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int N;
    in(N);
    vector<int> A(N);
    vector<int> B(N);
    for (int i = 0; i < N; ++i) in(A[i]);
    for (int i = 0; i < N; ++i) in(B[i]);
    for (int i = 0; i < N; ++i) --A[i];
    for (int i = 0; i < N; ++i) --B[i];
    // step 1a: compute L_i and R_i for the case A_i in [B_j, A_j].
    vector<int> at_A(2 * N, -1);
    vector<int> at_B(2 * N, -1);
    for (int i = 0; i < N; ++i) {
        at_A[A[i]] = at_B[B[i]] = i;
    }
    vector<int> L(N, -1);
    vector<int> R(N, 1e9);
    set<int> open;
    for (int i = 0; i < 2 * N; ++i) {
        if (at_B[i] != -1) {
            open.insert(at_B[i]);
        } else if (at_A[i] != -1) {
            int j = at_A[i];
            open.erase(j);
            auto it = open.lower_bound(j);
            if (it != open.end()) R[j] = *it;
            if (it != open.begin()) {
                --it;
                L[j] = *it;
            }
        }
    }
    // step 1b: compute L_i and R_i for the case A_j in [B_i, A_i].
    tree.resize(8 * N, -1);
    for (int i = 0; i < N; ++i) {
        L[i] = max(L[i], query(1, 0, 2 * N - 1, B[i], A[i]));
        upd(1, 0, 2 * N - 1, A[i], i);
    }
    tree.clear();
    tree.resize(8 * N, -1e9);
    for (int i = N - 1; i >= 0; --i) {
        R[i] = min(R[i], -query(1, 0, 2 * N - 1, B[i], A[i]));
        upd(1, 0, 2 * N - 1, A[i], -i);
    }
    vector<array<int, 3>> segs;
    for (int i = 0; i < N; ++i) segs.push_back({R[i], L[i], i});
    sort(segs.begin(), segs.end());
    // step 2: process queries
    int Q;
    in(Q);
    vector<array<int, 3>> queries;
    for (int i = 0; i < Q; ++i) {
        int l, r;
        in(l);
        in(r);
        --l;
        --r;
        queries.push_back({r, l, i});
    }
    sort(queries.begin(), queries.end());
    vector<bool> ans(Q, true);
    int ptr = 0;
    tree.clear();
    tree.resize(4 * N, -1e9);
    vector<vector<pair<int, int>>> by_l(N);
    base = N + Q;
    for (int i = 0; i < N; ++i) {
        int l = segs[i][1];
        int r = segs[i][0];
        int j = segs[i][2];
        while (ptr < Q && queries[ptr][0] < r) {
            int lh = queries[ptr][1];
            int rh = queries[ptr][0];
            int ind = queries[ptr][2];
            by_l[lh].push_back({rh, ind});
            upd(1, 0, N - 1, lh, f(rh, lh, ind));
            ++ptr;
        }
        while (1) {
            int mx = query(1, 0, N - 1, l + 1, j);
            if (mx == -1e9) break;
            int rh = mx / (base * base);
            int lh = (mx - rh * base * base) / base;
            int ind = mx % base;
            if (rh < j) break;
            ans[ind] = false;
            by_l[lh].pop_back();
            if (by_l[lh].empty()) upd(1, 0, N - 1, lh, -1e9);
            else upd(1, 0, N - 1, lh, f(by_l[lh].back().first, lh, by_l[lh].back().second));
        }
    }
    for (int i = 0; i < Q; ++i) {
        if (ans[i]) out("Yes");
        else out("No");
        out("\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...