Problem p04052 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#define D(a) cerr << #a << " = " << a << endl
#else
#define D(a)
#define cerr false && cerr
#endif
#define fastio                                                                 \
  ios_base::sync_with_stdio(0);                                                \
  cin.tie(0)
#define dforsn(i, s, n) for (int i = int(n - 1); i >= int(s); i--)
#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define dforn(i, n) dforsn(i, 0, n)
#define forn(i, n) forsn(i, 0, n)
#define all(a) a.begin(), a.end()
#define si(a) int((a).size())
#define pb emplace_back
#define mp make_pair
#define snd second
#define fst first
#define endl '\n'
using pii = pair<int, int>;
using vi = vector<int>;
using ll = long long;

const int N = 5e4;
const int INF = 1e9;

struct RMQ {
  int neutro = -1e9;
  int sz;
  pii t[4 * N];
  int &operator[](int p) {
    t[sz + p].snd = p;
    return t[sz + p].fst;
  }
  void init(int n) { // O(n)
    sz = 1 << (32 - __builtin_clz(n));
    forn(i, 2 * sz) t[i] = {neutro, -1};
  }
  void updall() { // O(n)
    dforsn(i, 0, sz) t[i] = max(t[2 * i], t[2 * i + 1]);
  }
  pii get(int i, int j) { return get(i, j, 1, 0, sz); }
  pii get(int i, int j, int n, int a, int b) { // O(lg n)
    if (j <= a || i >= b)
      return mp(neutro, -1);
    if (i <= a && b <= j)
      return t[n];

    int c = (a + b) / 2;
    return max(get(i, j, 2 * n, a, c), get(i, j, 2 * n + 1, c, b));
  }
  void set(int p, int val) { // O(lg n)
    pii act = {val, p};
    for (p += sz; p > 0 && t[p].fst != val;) {
      t[p] = act, p /= 2;
      act = max(t[p * 2], t[p * 2 + 1]);
    }
  }
} rmq;

int main() {
  fastio;

  int n, k;
  cin >> n >> k;
  vi p(n);
  for (int &x : p) {
    cin >> x;
    x--;
  }

  rmq.init(n);
  forn(i, n) rmq[i] = p[i];
  rmq.updall();

  auto is_maximum = [&p, k, n](int i) {
    int l = max(i - k + 1, 0), r = min(i + k, n);
    return p[i] == rmq.get(l, r).fst;
  };

  priority_queue<int> local_maximums;
  forn(i, n) if (is_maximum(i)) local_maximums.push(i);

  vi ans(n);
  dforn(next_id, n) {
    int local_maximum = -1;
    while (local_maximum == -1 || !is_maximum(local_maximum))
      local_maximum = local_maximums.top(), local_maximums.pop();

    ans[local_maximum] = next_id;
    rmq.set(local_maximum, -INF);

    auto update = [is_maximum, &local_maximums, n, k](int block) {
      if (block < 0 || block * k >= n)
        return;

      int l = block * k, r = min((block + 1) * k, n);

      int candidate = rmq.get(l, r).snd;
      if (candidate >= 0 && is_maximum(candidate))
        local_maximums.push(candidate);
    };

    int block_number = local_maximum / k;
    forsn(block, block_number - 1, block_number + 2) update(block);
  }

  for (int &x : ans)
    cout << x + 1 << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#define D(a) cerr << #a << " = " << a << endl
#else
#define D(a)
#define cerr false && cerr
#endif
#define fastio                                                                 \
  ios_base::sync_with_stdio(0);                                                \
  cin.tie(0)
#define dforsn(i, s, n) for (int i = int(n - 1); i >= int(s); i--)
#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define dforn(i, n) dforsn(i, 0, n)
#define forn(i, n) forsn(i, 0, n)
#define all(a) a.begin(), a.end()
#define si(a) int((a).size())
#define pb emplace_back
#define mp make_pair
#define snd second
#define fst first
#define endl '\n'
using pii = pair<int, int>;
using vi = vector<int>;
using ll = long long;

const int N = 5e5;
const int INF = 1e9;

struct RMQ {
  int neutro = -1e9;
  int sz;
  pii t[4 * N];
  int &operator[](int p) {
    t[sz + p].snd = p;
    return t[sz + p].fst;
  }
  void init(int n) { // O(n)
    sz = 1 << (32 - __builtin_clz(n));
    forn(i, 2 * sz) t[i] = {neutro, -1};
  }
  void updall() { // O(n)
    dforsn(i, 0, sz) t[i] = max(t[2 * i], t[2 * i + 1]);
  }
  pii get(int i, int j) { return get(i, j, 1, 0, sz); }
  pii get(int i, int j, int n, int a, int b) { // O(lg n)
    if (j <= a || i >= b)
      return mp(neutro, -1);
    if (i <= a && b <= j)
      return t[n];

    int c = (a + b) / 2;
    return max(get(i, j, 2 * n, a, c), get(i, j, 2 * n + 1, c, b));
  }
  void set(int p, int val) { // O(lg n)
    pii act = {val, p};
    for (p += sz; p > 0 && t[p].fst != val;) {
      t[p] = act, p /= 2;
      act = max(t[p * 2], t[p * 2 + 1]);
    }
  }
} rmq;

int main() {
  fastio;

  int n, k;
  cin >> n >> k;
  vi p(n);
  for (int &x : p) {
    cin >> x;
    x--;
  }

  rmq.init(n);
  forn(i, n) rmq[i] = p[i];
  rmq.updall();

  auto is_maximum = [&p, k, n](int i) {
    int l = max(i - k + 1, 0), r = min(i + k, n);
    return p[i] == rmq.get(l, r).fst;
  };

  priority_queue<int> local_maximums;
  forn(i, n) if (is_maximum(i)) local_maximums.push(i);

  vi ans(n);
  dforn(next_id, n) {
    int local_maximum = -1;
    while (local_maximum == -1 || !is_maximum(local_maximum))
      local_maximum = local_maximums.top(), local_maximums.pop();

    ans[local_maximum] = next_id;
    rmq.set(local_maximum, -INF);

    auto update = [is_maximum, &local_maximums, n, k](int block) {
      if (block < 0 || block * k >= n)
        return;

      int l = block * k, r = min((block + 1) * k, n);

      int candidate = rmq.get(l, r).snd;
      if (candidate >= 0 && is_maximum(candidate))
        local_maximums.push(candidate);
    };

    int block_number = local_maximum / k;
    forsn(block, block_number - 1, block_number + 2) update(block);
  }

  for (int &x : ans)
    cout << x + 1 << endl;

  return 0;
}