Problem p04052 (C++)

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

#define maxn 100010
#define mp make_pair

using namespace std;

pair<int, int> drzewo[4 * maxn];
bool czy[maxn];
priority_queue<int> prl;
int n, k, r = 1;
int odp[maxn];

pair<int, int> find_max(int gdzie, int pp, int pk, int zp, int zk) {
  // cout << gdzie << endl;
  if (zp > pk || zk < pp)
    return mp(0, -1);
  if (zp <= pp && zk >= pk)
    return drzewo[gdzie];
  int sr = (pp + pk) / 2;
  return max(find_max(2 * gdzie, pp, sr, zp, zk),
             find_max(2 * gdzie + 1, sr + 1, pk, zp, zk));
}

bool is_local_maximum(int x) {
  // cout << x << endl;
  pair<int, int> a = find_max(1, 1, r, x - k + 1, x + k - 1);
  return a.first == drzewo[x + r - 1].first;
}

void inserty(int x) {
  drzewo[x].first = 0;
  x /= 2;
  while (x != 0) {
    drzewo[x] = max(drzewo[2 * x], drzewo[2 * x + 1]);
    x /= 2;
  }
}

pair<int, int> find_segment(int x) {
  return mp((x / k) * k, (x / k) * k + k - 1);
}

int main() {
  scanf("%d%d", &n, &k);
  while (r < n)
    r *= 2;
  for (int i = 0; i < n; ++i) {
    scanf("%d", &drzewo[i + r].first);
    drzewo[i + r].second = i;
  }
  for (int i = n + r; i < 2 * r; ++i)
    drzewo[i] = mp(0, -1);
  for (int i = r - 1; i > 0; --i)
    drzewo[i] = max(drzewo[2 * i], drzewo[2 * i + 1]);
  // cout << "S" << endl;
  for (int i = 0; i < n; ++i) {
    if (is_local_maximum(i + 1)) {
      prl.push(i);
      czy[i] = true;
      // cout << i << endl;
    }
  }
  int wsk = n;
  // cout << "S" << endl;
  while (!prl.empty()) {
    odp[prl.top()] = wsk;
    --wsk;
    inserty(prl.top() + r);
    pair<int, int> a = find_segment(prl.top());
    a.first++;
    a.second++;
    prl.pop();
    pair<int, int> b = find_max(1, 1, r, a.first, a.second);
    // cout << b.first << " " << b.second << endl;
    if (b.second != -1 && b.first != 0) {
      if (!czy[b.second] && is_local_maximum(b.second + 1)) {
        czy[b.second] = true;
        prl.push(b.second);
      }
    }
    b = find_max(1, 1, r, a.first - k, a.second - k);
    if (b.second != -1 && b.first != 0) {
      if (!czy[b.second] && is_local_maximum(b.second + 1)) {
        czy[b.second] = true;
        prl.push(b.second);
      }
    }
    b = find_max(1, 1, r, a.first + k, a.second + k);
    if (b.second != -1 && b.first != 0) {
      if (!czy[b.second] && is_local_maximum(b.second + 1)) {
        czy[b.second] = true;
        prl.push(b.second);
      }
    }
  }
  for (int i = 0; i < n; ++i)
    printf("%d\n", odp[i]);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

#define maxn 500010
#define mp make_pair

using namespace std;

pair<int, int> drzewo[4 * maxn];
bool czy[maxn];
priority_queue<int> prl;
int n, k, r = 1;
int odp[maxn];

pair<int, int> find_max(int gdzie, int pp, int pk, int zp, int zk) {
  // cout << gdzie << endl;
  if (zp > pk || zk < pp)
    return mp(0, -1);
  if (zp <= pp && zk >= pk)
    return drzewo[gdzie];
  int sr = (pp + pk) / 2;
  return max(find_max(2 * gdzie, pp, sr, zp, zk),
             find_max(2 * gdzie + 1, sr + 1, pk, zp, zk));
}

bool is_local_maximum(int x) {
  // cout << x << endl;
  pair<int, int> a = find_max(1, 1, r, x - k + 1, x + k - 1);
  return a.first == drzewo[x + r - 1].first;
}

void inserty(int x) {
  drzewo[x].first = 0;
  x /= 2;
  while (x != 0) {
    drzewo[x] = max(drzewo[2 * x], drzewo[2 * x + 1]);
    x /= 2;
  }
}

pair<int, int> find_segment(int x) {
  return mp((x / k) * k, (x / k) * k + k - 1);
}

int main() {
  scanf("%d%d", &n, &k);
  while (r < n)
    r *= 2;
  for (int i = 0; i < n; ++i) {
    scanf("%d", &drzewo[i + r].first);
    drzewo[i + r].second = i;
  }
  for (int i = n + r; i < 2 * r; ++i)
    drzewo[i] = mp(0, -1);
  for (int i = r - 1; i > 0; --i)
    drzewo[i] = max(drzewo[2 * i], drzewo[2 * i + 1]);
  // cout << "S" << endl;
  for (int i = 0; i < n; ++i) {
    if (is_local_maximum(i + 1)) {
      prl.push(i);
      czy[i] = true;
      // cout << i << endl;
    }
  }
  int wsk = n;
  // cout << "S" << endl;
  while (!prl.empty()) {
    odp[prl.top()] = wsk;
    --wsk;
    inserty(prl.top() + r);
    pair<int, int> a = find_segment(prl.top());
    a.first++;
    a.second++;
    prl.pop();
    pair<int, int> b = find_max(1, 1, r, a.first, a.second);
    // cout << b.first << " " << b.second << endl;
    if (b.second != -1 && b.first != 0) {
      if (!czy[b.second] && is_local_maximum(b.second + 1)) {
        czy[b.second] = true;
        prl.push(b.second);
      }
    }
    b = find_max(1, 1, r, a.first - k, a.second - k);
    if (b.second != -1 && b.first != 0) {
      if (!czy[b.second] && is_local_maximum(b.second + 1)) {
        czy[b.second] = true;
        prl.push(b.second);
      }
    }
    b = find_max(1, 1, r, a.first + k, a.second + k);
    if (b.second != -1 && b.first != 0) {
      if (!czy[b.second] && is_local_maximum(b.second + 1)) {
        czy[b.second] = true;
        prl.push(b.second);
      }
    }
  }
  for (int i = 0; i < n; ++i)
    printf("%d\n", odp[i]);
  return 0;
}