Problem p03372 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int ll
using pi = pair<int, int>; // fs: value, sc : pos
template <class T, class S> void cmin(T &a, const S &b) {
  if (a > b)
    a = b;
}
template <class T, class S> void cmax(T &a, const S &b) {
  if (a < b)
    a = b;
}
int get_cost(pi lst, int cpos, int nvalue) {
  return nvalue + lst.first - (cpos - lst.second);
}
template <class T, class Func = function<T(T, T)>> class segtree {
  vector<T> obj;
  int offset;
  Func updater;
  T e;
  int bufsize(int num) {
    int i = 1;
    for (; num + 1 > i; i <<= 1)
      ;
    offset = i - 1;
    return (i << 1) - 1;
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return e;
    if (a <= l && r <= b)
      return obj[k];
    else
      return updater(query(a, b, k * 2 + 1, l, (l + r) / 2),
                     query(a, b, k * 2 + 2, (l + r) / 2, r));
  }

public:
  T query(int a, int b) { //[a,b)
    return query(a, b, 0, 0, offset + 1);
  }
  void updateall(int l = 0, int r = -1) {
    if (r < 0)
      r = offset + 1;
    l += offset, r += offset;
    do {
      l = (l - 1) >> 1, r = (r - 1) >> 1;
      for (int i = l; i < r; i++)
        obj[i] = updater(obj[i * 2 + 1], obj[i * 2 + 2]);
    } while (l);
  }
  void update(int k, T &a) {
    k += offset;
    obj[k] = a;
    while (k) {
      k = (k - 1) >> 1;
      obj[k] = updater(obj[k * 2 + 1], obj[k * 2 + 2]);
    }
  }
  segtree(int n, T e, const Func &updater = Func())
      : obj(bufsize(n), e), e(e), updater(updater) {}
  segtree(vector<T> &vec, T e, const Func &updater = Func())
      : obj(bufsize(vec.size()), e), e(e), updater(updater) {
    copy(vec.begin(), vec.end(), obj.begin() + offset);
    updateall();
  }
  typename vector<T>::reference operator[](int n) { return obj[n + offset]; }
};

signed main() {
  int N, C;
  cin >> N >> C;
  vector<vector<pi>> dp(2, vector<pi>(N, make_pair(-1LL, -1LL)));
  vector<pi> v(N);
  for (auto &p : v) {
    cin >> p.second >> p.first;
  }
  for (int i = 0; i < N; ++i) {
    int nvalue = v[i].first;
    int npos = v[i].second;
    if (i == 0) {
      dp[1][0].first = nvalue - npos;
      dp[1][0].second = npos;
      dp[0][0].first = 0;
      dp[0][0].second = 0;

    } else {
      dp[1][i].first = max(get_cost(dp[1][i - 1], npos, nvalue),
                           get_cost(dp[0][i - 1], npos, nvalue));

      dp[1][i].second = npos;
      dp[0][i] = (dp[0][i - 1].first > dp[1][i - 1].first ? dp[0][i - 1]
                                                          : dp[1][i - 1]);
    }
  }
  vector<vector<pi>> rdp(2, vector<pi>(N, make_pair(-1LL, -1LL)));
  vector<pi> rv = v;
  reverse(rv.begin(), rv.end());
  for (auto &p : rv)
    p.second = C - p.second;
  for (int i = 0; i < N; ++i) {
    int nvalue = rv[i].first;
    int npos = rv[i].second;
    if (i == 0) {
      rdp[1][0].first = nvalue - npos;
      rdp[1][0].second = npos;
      rdp[0][0].first = 0;
      rdp[0][0].second = 0;

    } else {
      rdp[1][i].first = max(get_cost(rdp[1][i - 1], npos, nvalue),
                            get_cost(rdp[0][i - 1], npos, nvalue));
      rdp[1][i].second = npos;
      rdp[0][i] = (rdp[0][i - 1].first > rdp[1][i - 1].first ? rdp[0][i - 1]
                                                             : rdp[1][i - 1]);
    }
  }
  int ans = -1;
  auto maxf = [](pi a, pi b) { return (a.first > b.first ? a : b); };
  pi base = make_pair(0, 0);
  auto s1 = segtree<pi>(rdp[1], base, maxf);
  auto s0 = segtree<pi>(rdp[0], base, maxf);
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < 2; ++j) {
      auto crt = dp[j][i];
      int range = N - i - 1;
      auto a = s1.query(0, range);
      auto b = s0.query(0, range);
      cmax(ans, crt.first);
      cmax(ans, rdp[i][j].first);
      int cnd = crt.first + a.first - min(crt.second, a.second);
      cmax(cnd, crt.first + b.first - min(crt.second, b.second));
      cmax(ans, cnd);
    }
  }
  cout << max(ans, 0LL) << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define int ll
using pi = pair<int, int>; // fs: value, sc : pos
template <class T, class S> void cmin(T &a, const S &b) {
  if (a > b)
    a = b;
}
template <class T, class S> void cmax(T &a, const S &b) {
  if (a < b)
    a = b;
}
int get_cost(pi lst, int cpos, int nvalue) {
  return nvalue + lst.first - (cpos - lst.second);
}
template <class T, class Func = function<T(T, T)>> class segtree {
  vector<T> obj;
  int offset;
  Func updater;
  T e;
  int bufsize(int num) {
    int i = 1;
    for (; num + 1 > i; i <<= 1)
      ;
    offset = i - 1;
    return (i << 1) - 1;
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return e;
    if (a <= l && r <= b)
      return obj[k];
    else
      return updater(query(a, b, k * 2 + 1, l, (l + r) / 2),
                     query(a, b, k * 2 + 2, (l + r) / 2, r));
  }

public:
  T query(int a, int b) { //[a,b)
    return query(a, b, 0, 0, offset + 1);
  }
  void updateall(int l = 0, int r = -1) {
    if (r < 0)
      r = offset + 1;
    l += offset, r += offset;
    do {
      l = (l - 1) >> 1, r = (r - 1) >> 1;
      for (int i = l; i < r; i++)
        obj[i] = updater(obj[i * 2 + 1], obj[i * 2 + 2]);
    } while (l);
  }
  void update(int k, T &a) {
    k += offset;
    obj[k] = a;
    while (k) {
      k = (k - 1) >> 1;
      obj[k] = updater(obj[k * 2 + 1], obj[k * 2 + 2]);
    }
  }
  segtree(int n, T e, const Func &updater = Func())
      : obj(bufsize(n), e), e(e), updater(updater) {}
  segtree(vector<T> &vec, T e, const Func &updater = Func())
      : obj(bufsize(vec.size()), e), e(e), updater(updater) {
    copy(vec.begin(), vec.end(), obj.begin() + offset);
    updateall();
  }
  typename vector<T>::reference operator[](int n) { return obj[n + offset]; }
};

signed main() {
  int N, C;
  cin >> N >> C;
  vector<vector<pi>> dp(2, vector<pi>(N, make_pair(-1LL, -1LL)));
  vector<pi> v(N);
  for (auto &p : v) {
    cin >> p.second >> p.first;
  }
  for (int i = 0; i < N; ++i) {
    int nvalue = v[i].first;
    int npos = v[i].second;
    if (i == 0) {
      dp[1][0].first = nvalue - npos;
      dp[1][0].second = npos;
      dp[0][0].first = 0;
      dp[0][0].second = 0;

    } else {
      dp[1][i].first = max(get_cost(dp[1][i - 1], npos, nvalue),
                           get_cost(dp[0][i - 1], npos, nvalue));

      dp[1][i].second = npos;
      dp[0][i] = (dp[0][i - 1].first > dp[1][i - 1].first ? dp[0][i - 1]
                                                          : dp[1][i - 1]);
    }
  }
  vector<vector<pi>> rdp(2, vector<pi>(N, make_pair(-1LL, -1LL)));
  vector<pi> rv = v;
  reverse(rv.begin(), rv.end());
  for (auto &p : rv)
    p.second = C - p.second;
  for (int i = 0; i < N; ++i) {
    int nvalue = rv[i].first;
    int npos = rv[i].second;
    if (i == 0) {
      rdp[1][0].first = nvalue - npos;
      rdp[1][0].second = npos;
      rdp[0][0].first = 0;
      rdp[0][0].second = 0;

    } else {
      rdp[1][i].first = max(get_cost(rdp[1][i - 1], npos, nvalue),
                            get_cost(rdp[0][i - 1], npos, nvalue));
      rdp[1][i].second = npos;
      rdp[0][i] = (rdp[0][i - 1].first > rdp[1][i - 1].first ? rdp[0][i - 1]
                                                             : rdp[1][i - 1]);
    }
  }
  int ans = -1;
  auto maxf = [](pi a, pi b) { return (a.first > b.first ? a : b); };
  pi base = make_pair(0, 0);
  auto s1 = segtree<pi>(rdp[1], base, maxf);
  auto s0 = segtree<pi>(rdp[0], base, maxf);
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < 2; ++j) {
      auto crt = dp[j][i];
      int range = N - i - 1;
      auto a = s1.query(0, range);
      auto b = s0.query(0, range);
      cmax(ans, crt.first);
      cmax(ans, rdp[j][i].first);
      int cnd = crt.first + a.first - min(crt.second, a.second);
      cmax(cnd, crt.first + b.first - min(crt.second, b.second));
      cmax(ans, cnd);
    }
  }
  cout << max(ans, 0LL) << endl;
}