Problem p02537 (C++) — buggy submission, verdict: Runtime Error

#include "assert.h"
#include "math.h"
#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int inf = std::numeric_limits<int>().max();

#define BUFF ios::sync_with_stdio(false)
#define epsilon 1e-07
#define pi 2 * acos(0.0);
#define mod 1000000007 // 1e9+7
#define ll long long
#define cerr                                                                   \\
  if (false)                                                                   \\
  cerr
#define watch(x) cerr << #x << " = " << x << endl;

/*

        Segment Tree
                - utilizada para consultar e atualizar valores em intervalos de
   v[0..n).
                - operações:
                        - build - O(n lg n).
                        - search - O(lg n) - consulta o valor mínimo contido no
   intervalo [0..n-1].
                        - add - O(lg n) - atualiza o valor de v(i).

                        - soma (nulo = 0), mínimo (nulo = inf), etc.

*/

void build_segment_tree(vector<int> &v, vector<int> &st, int nulo) {
  int n = v.size();
  int k = 1;

  while (pow(2, k) < n)
    k++;
  int ns = pow(2, k);
  st.resize(2 * ns);

  for (int i = ns; i < 2 * ns; i++) {
    if (i - ns < n)
      st[i] = v[i - ns];
    else
      st[i] = nulo;
  }

  int start = ns;
  int delta = 2 * ns;
  for (int pot = k; pot >= 0; pot--) {
    for (int i = start; i < delta; i += 2) {
      st[i / 2] = max(st[i], st[i + 1]);
    }
    delta = start;
    start /= 2;
  }
}

int search(int i, int j, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  j += n;
  bool i_last = false;
  bool j_last = false;
  int t = 0;
  while (i <= j) {
    if (!i_last and (i % 2 == 1 or j_last)) {
      t = max(t, st[i]);
      i++;
    }
    if (!j_last and (j % 2 == 0 or i_last)) {
      t = max(t, st[j]);
      j--;
    }
    if (!i_last and i % 2 == 1) {
      i_last = true;
    }
    if (!j_last and j % 2 == 0) {
      j_last = true;
    }
    i = i / 2;
    j = j / 2;
  }
  return t;
}

void add(int x, int i, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  st[i] = x;
  int t = st[i];
  while (i >= 1) {
    st[i] = max(st[i], t);
    i /= 2;
  }
}

void show(vector<int> &st) {
  cout << st.size() << ": ";
  for (int i = 0; i < st.size(); i++) {
    cout << st[i] << " ";
  }
  cout << endl;
}

int main() {
  int n, k;
  cin >> n >> k;

  vector<int> v(n, 0);
  for (int i = 0; i < n; i++) {
    cin >> v[i];
  }

  vector<int> w(300001, 0);
  vector<int> st;
  build_segment_tree(w, st, 0);

  for (int i = 0; i < n; i++) {
    int a, b;
    a = max(0, v[i] - k);
    b = min(300001 - 1, v[i] + k);
    int t = search(a, b, st);
    add(t + 1, v[i], st);
    //		cout << v[i] << " ab: " << a << " " << b << ": " << search(a, b, st)
    //<< endl;
  }

  //	add(10, 4, st);
  //	add(-9, 1, st);
  //	show(st);

  cout << search(0, 300001 - 1, st) << endl;
}


Error: 0

Fixed submission:

#include "assert.h"
#include "math.h"
#include <algorithm>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

int inf = std::numeric_limits<int>().max();

#define BUFF ios::sync_with_stdio(false)
#define epsilon 1e-07
#define pi 2 * acos(0.0);
#define mod 1000000007 // 1e9+7
#define ll long long
#define cerr                                                                   \\
  if (false)                                                                   \\
  cerr
#define watch(x) cerr << #x << " = " << x << endl;

/*

        Segment Tree
                - utilizada para consultar e atualizar valores em intervalos de
   v[0..n).
                - operações:
                        - build - O(n lg n).
                        - search - O(lg n) - consulta o valor mínimo contido no
   intervalo [0..n-1].
                        - add - O(lg n) - atualiza o valor de v(i).

                        - soma (nulo = 0), mínimo (nulo = inf), etc.

*/

void build_segment_tree(vector<int> &v, vector<int> &st, int nulo) {
  int n = v.size();
  int k = 1;

  while (pow(2, k) < n)
    k++;
  int ns = pow(2, k);
  st.resize(2 * ns);

  for (int i = ns; i < 2 * ns; i++) {
    if (i - ns < n)
      st[i] = v[i - ns];
    else
      st[i] = nulo;
  }

  int start = ns;
  int delta = 2 * ns;
  for (int pot = k; pot >= 0; pot--) {
    int sz = pow(2, pot);
    for (int i = start; i < delta; i += 2) {
      st[i / 2] = max(st[i], st[i + 1]);
    }
    delta = start;
    start /= 2;
  }
}

int search(int i, int j, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  j += n;
  bool i_last = false;
  bool j_last = false;
  int t = 0;
  while (i <= j) {
    if (!i_last and (i % 2 == 1 or j_last)) {
      t = max(t, st[i]);
      i++;
    }
    if (!j_last and (j % 2 == 0 or i_last)) {
      t = max(t, st[j]);
      j--;
    }
    if (!i_last and i % 2 == 1) {
      i_last = true;
    }
    if (!j_last and j % 2 == 0) {
      j_last = true;
    }
    i = i / 2;
    j = j / 2;
  }
  return t;
}

void add(int x, int i, vector<int> &st) {
  int n = st.size() / 2;
  i += n;
  st[i] = x;
  int t = st[i];
  while (i >= 1) {
    st[i] = max(st[i], t);
    i /= 2;
  }
}

void show(vector<int> &st) {
  cout << st.size() << ": ";
  for (int i = 0; i < st.size(); i++) {
    cout << st[i] << " ";
  }
  cout << endl;
}

int main() {
  int n, k;
  cin >> n >> k;

  vector<int> v(n, 0);
  for (int i = 0; i < n; i++) {
    cin >> v[i];
    v[i]--;
  }

  vector<int> w(n, 0);
  vector<int> st;
  build_segment_tree(w, st, 0);

  for (int i = 0; i < n; i++) {
    int a, b;
    a = max(0, v[i] - k);
    b = min(n - 1, v[i] + k);
    int t = search(a, b, st);
    add(t + 1, v[i], st);
    // cout << v[i] << " ab: " << a << " " << b << ": " << search(a, b, st) <<
    // endl;
  }

  //	add(10, 4, st);
  //	add(-9, 1, st);
  //	show(st);

  cout << search(0, n - 1, st) << endl;
}