#include <bits/stdc++.h>
using namespace std;
int bitmask(int n, int d, vector<int> a) {
    int ans = 0;
    for (int mask = 1; mask < (1 << n); mask++) {
        vector<int> active; for (int i = 0; i < n; i++) if (mask & (1 << i)) active.push_back(i);
        int calc = 1, cmax = a[active[0]];
        for (int i = 1; i < active.size(); i++) {
            if (active[i] - active[i-1] > d) {
                calc = 0; break;
            }
            if (a[active[i]] > cmax) {
                cmax = a[active[i]];
                calc++;
            }
        }
        ans = max(ans, calc);
    }
    return ans;
}
// because reachability is monotone forwards, we could do range chmax for all the nodes i can reach
// could get 12 pts for N = 1 as follows: (1) use binary search to find largest array starting at i where max(arr) <= a[i]
//                                            this gives reachable[i]
//                                        (2) ...
struct SegTree {
    int n; vector<int> st;
    SegTree() {};
    SegTree(int N) {
        n = N; st.resize(4*n);
    }
    int update(int i, int l, int r, int k, int v) {
        if (!(l <= k && k < r)) return st[i];
        if (l + 1 == r) return st[i] = v;
        int m = l + (r - l) / 2;
        return st[i] = max(update(2*i+1, l, m, k, v), update(2*i+2, m, r, k, v));
    }
    int query(int i, int l, int r, int ql, int qr) {
        if (r <= ql || qr <= l) return 0;
        if (ql <= l && r <= qr) return st[i];
        int m = l + (r - l) / 2;
        return max(query(2*i+1, l, m, ql, qr), query(2*i+2, m, r, ql, qr));
    }
    void update(int k, int v) {
        update(0, 0, n, k, v);
    }
    int query(int l, int r) {
        return query(0, 0, n, l, r);
    }
    void trace() {
        for (int i = 0; i < n; i++) cout << query(i, i+1) << " "; cout << "\n";
    }
};
                                              
int dp(int n, int d, vector<int> a) {
    vector<int> indices(n); iota(indices.begin(), indices.end(), 0);
    sort(indices.begin(), indices.end(), [&](int i, int j) {return a[i] == a[j] ? i > j : a[i] < a[j];});
    vector<int> ridx(n); for (int i = 0; i < n; i++) ridx[indices[i]] = i;
    vector<vector<int>> ends(n+1, vector<int>());
    auto rmq2 = SegTree(n); for (int i = 0; i < n; i++) rmq2.update(i, a[i]);
    for (int i = 0; i < n; i++) {
        int max_dist = 0, prev_se = i;
        // for (int j = i; j < n; j++) {
        //     max_dist = max(max_dist, j - prev_se);
        //     if (a[j] <= a[i]) prev_se = j;
        //     if (max_dist > d) {
        //         ends[j].push_back(i);
        //         break;
        //     }
        // }
        int lo = i, hi = n - 1;
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            bool check = rmq2.query(i, mid + 1) > a[i];
            if (check) {
                hi = mid;
            } else {
                lo = mid + 1;
            }
        }
        ends[lo+1].push_back(i);
    }
    vector<int> DP(n, 0);
    auto st = SegTree(n);
    for (int i = 0; i < n; i++) {
        for (auto &el : ends[i]) {
            st.update(ridx[el], 0);
        }
        DP[i] = st.query(0, ridx[i]) + 1;
        st.update(ridx[i], DP[i]);
    }
    return *max_element(DP.begin(), DP.end());
}
void debug() {
    mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
    uniform_int_distribution dist(0, 5);
    for (int TRIAL = 0; TRIAL < 1'000; TRIAL++) {
        int N = 6; vector<int> INPUT; for (int i = 0; i < N; i++) INPUT.push_back(dist(rng));
        for (int D = 1; D <= N; D++) {
            int bm = bitmask(N, D, INPUT);
            int dpa = dp(N, D, INPUT);
            if (bm != dpa) {
                cout << "Failure on N: " << N << " D: " << D << " and array:"; for (auto &el : INPUT) cout << " " << el; cout << "\n";
                cout << "Bitmask: " << bm << " DP: " << dpa << "\n";
                break; 
            }
        }
    }
}
int main() {
    // debug();
    cin.tie(0)->sync_with_stdio(0);
    int n, d; cin >> n >> d;
    vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i];
    cout << dp(n, d, a) << "\n";
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |