Submission #1348041

#TimeUsernameProblemLanguageResultExecution timeMemory
1348041killerzaluuAlternating Heights (CCO22_day1problem1)C++20
0 / 25
68 ms3572 KiB
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k, q;
    cin >> n >> k >> q;

    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];

    vector<int> dp(n + 1, n);

    // For every adjacency i -> i+1, compress the unordered pair.
    // x[i], y[i] with x[i] < y[i]
    // t[i] = 0 if a[i] < a[i+1], 1 otherwise
    // badself if a[i] == a[i+1]
    vector<int> x(n), y(n), t(n), self(n);
    for (int i = 1; i < n; i++) {
        if (a[i] == a[i + 1]) {
            self[i] = 1;
            x[i] = y[i] = a[i];
            t[i] = 0;
        } else {
            self[i] = 0;
            x[i] = min(a[i], a[i + 1]);
            y[i] = max(a[i], a[i + 1]);
            t[i] = (a[i] > a[i + 1]);
        }
    }

    // For current left endpoint l, an edge at position i means:
    // if (i-l)%2==0 then required relation is a[i] > a[i+1]
    // else required relation is a[i] < a[i+1]
    //
    // Suppose edge i is between u and v, with u < v.
    // If t[i]=0, then actual order in array is u,v.
    // If t[i]=1, then actual order in array is v,u.
    //
    // We maintain whether pair (u,v) is forced as u<v or u>v in current window.
    // dir = t[i] xor ((i-l)%2==0 ? 1 : 0)
    // since when parity says ">", if array order is u,v then requirement is u>v.
    //
    // To support sliding l, we process separately for l parity 1 and 0.
    // For fixed l parity, (i-l)%2 depends only on parity of i.

    auto solve_parity = [&](int start_parity, vector<int>& ans) {
        unordered_map<long long, int> cnt0, cnt1;
        cnt0.reserve(n * 2);
        cnt1.reserve(n * 2);
        cnt0.max_load_factor(0.7f);
        cnt1.max_load_factor(0.7f);

        auto key = [&](int u, int v) -> long long {
            return 1LL * u * (k + 1) + v;
        };

        int bad = 0;
        int eq = 0;
        int r = start_parity; // window over edges [l..r-1], so r is current right endpoint in array positions
        if (r == 0) r = 2;

        for (int l = start_parity; l <= n; l += 2) {
            if (r < l) r = l;

            while (r < n) {
                int i = r; // adding edge i = (r, r+1)

                int add_eq = self[i];
                long long kk = key(x[i], y[i]);

                int dir;
                if ((i & 1) == (l & 1)) dir = t[i] ^ 1;
                else dir = t[i];

                int old0 = 0, old1 = 0;
                if (!self[i]) {
                    auto it0 = cnt0.find(kk);
                    if (it0 != cnt0.end()) old0 = it0->second;
                    auto it1 = cnt1.find(kk);
                    if (it1 != cnt1.end()) old1 = it1->second;
                }

                int nbad = bad;
                int neq = eq + add_eq;

                if (!self[i]) {
                    if (dir == 0) {
                        if (old0 == 0 && old1 > 0) nbad++;
                    } else {
                        if (old1 == 0 && old0 > 0) nbad++;
                    }
                }

                if (neq > 0 || nbad > 0) break;

                eq = neq;
                bad = nbad;
                if (!self[i]) {
                    if (dir == 0) cnt0[kk]++;
                    else cnt1[kk]++;
                }
                r++;
            }

            ans[l] = r;

            if (l < n) {
                int i = l; // remove edge l
                if (self[i]) {
                    eq--;
                } else {
                    long long kk = key(x[i], y[i]);
                    int dir;
                    if ((i & 1) == (l & 1)) dir = t[i] ^ 1;
                    else dir = t[i];

                    int old0 = cnt0[kk];
                    int old1 = cnt1[kk];

                    if (dir == 0) {
                        if (old0 == 1 && old1 > 0) bad--;
                        cnt0[kk]--;
                        if (cnt0[kk] == 0) cnt0.erase(kk);
                    } else {
                        if (old1 == 1 && old0 > 0) bad--;
                        cnt1[kk]--;
                        if (cnt1[kk] == 0) cnt1.erase(kk);
                    }
                }
            }
        }
    };

    solve_parity(1, dp);
    if (n >= 2) solve_parity(2, dp);

    while (q--) {
        int l, r;
        cin >> l >> r;
        cout << (dp[l] >= r ? "YES\n" : "NO\n");
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...