#include <bits/stdc++.h>
using namespace std;
struct stree {
    #define lc v*2
    #define rc v*2+1
    vector <int> tree;
    stree (int s) {
        tree.resize(s*4, -1);
    }
    void pushup(int v) {
        tree[v] = max(tree[lc], tree[rc]);
    }
    void update(int v, int tl, int tr, int p, int val) {
        if (tl > p || tr < p)
            return;
        if (tl == tr) {
            tree[v] = val;
            return;
        }
        int tm = (tl + tr) / 2;
        update(lc, tl, tm, p, val);
        update(rc, tm+1, tr, p, val);
        pushup(v);
    }
    int query(int v, int tl, int tr, int l, int r) {
        if (tl > r || tr < l)
            return -1;
        if (tl >= l && tr <= r)
            return tree[v];
        int tm = (tl + tr) / 2;
        int a = query(lc, tl, tm, l, r);
        int b = query(rc, tm+1, tr, l, r);
        return max(a, b);
    }
};
vector <int> compressed;
int get_id(int x) {
    return lower_bound(compressed.begin(), compressed.end(), x) - compressed.begin();
}
int main() {
    int n, d;
    cin >> n >> d;
    vector <int> nums(n+1);
    vector <pair <int, int>> nums2(n);
    compressed.resize(n+3);
    compressed[n+2] = -1e9;
    compressed[n+1] = -1;
    for (int i = 1; i <= n; i++) {
        cin >> nums[i];
        nums2[i-1].first = nums[i];
        nums2[i-1].second = i-1;
        compressed[i] = nums[i];
        compressed.push_back(nums[i]-1);
    }
    nums[0] = -1;
    sort(compressed.begin(), compressed.end());
    compressed.erase(unique(compressed.begin(), compressed.end()), compressed.end());
    sort(nums2.begin(), nums2.end());
    stree tree(n);
    vector <int> dp(n);
    set <pair <int, int>> indices;
    for (int i = 0; i < n; i++) {
        int x = nums2[i].first;
        int id = nums2[i].second;
        if (i > 0 && x != nums2[i-1].first) {
            for (auto i : indices) {
                tree.update(1, 0, n, i.first, i.second);
            }
            indices.clear();
        }
        if (x == nums2[0].first) {
            dp[id] = 1;
            tree.update(1, 0, n, id, 1);
        } else {
            int res = tree.query(1, 0, n, max(0, id-d), id);
            if (res == -1) {
                auto it = indices.lower_bound({id, 1e9});
                if (it != indices.begin() && !indices.empty()) {
                    it--;
                    if (id - it->first <= d)
                        dp[id] = it->second;
                } else {
                    dp[id] = 1;
                }
            } else {
                res = tree.query(1, 0, n, 0, id);
                dp[id] = res + 1;
            }
        }
        indices.insert({id, dp[id]});
    }
    cout << *max_element(dp.begin(), dp.end()) << '\n';
}
| # | 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... |