Problem p03616 (C++)

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

using namespace std;

const int N = 200 * 1000 + 17;
const int MOD = 1000 * 1000 * 1000 + 7;

struct segtree {
  int n;
  vector<long long> Tmin, Tmax, U;

  segtree() {}
  segtree(int n) : n(n) {
    Tmin.resize(4 * n);
    Tmax.resize(4 * n);
    U.resize(4 * n);
  }

  void push(int v) {
    Tmin[2 * v] += U[v];
    Tmax[2 * v] += U[v];
    U[2 * v] += U[v];
    Tmin[2 * v + 1] += U[v];
    Tmax[2 * v + 1] += U[v];
    U[2 * v + 1] += U[v];
    U[v] = 0;
  }

  void upd(int lq, int rq, long long x, int v, int l, int r) {
    if (r < lq || l > rq)
      return;

    if (lq <= l && r <= rq) {
      Tmin[v] += x;
      Tmax[v] += x;
      U[v] += x;
      return;
    }

    push(v);
    auto m = (l + r) / 2;
    upd(lq, rq, x, 2 * v, l, m);
    upd(lq, rq, x, 2 * v + 1, m + 1, r);
    Tmin[v] = min(Tmin[2 * v], Tmin[2 * v + 1]);
    Tmax[v] = max(Tmax[2 * v], Tmax[2 * v + 1]);
  }

  pair<long long, long long> get(int lq, int rq, int v, int l, int r) {
    if (r < lq || l > rq)
      return {1ll * MOD * MOD, -1ll * MOD * MOD};

    if (lq <= l && r <= rq)
      return {Tmin[v], Tmax[v]};

    push(v);
    auto m = (l + r) / 2;
    auto pl = get(lq, rq, 2 * v, l, m);
    auto pr = get(lq, rq, 2 * v + 1, m + 1, r);
    return {min(pl.first, pr.first), max(pl.second, pr.second)};
  }

  void upd(int lq, int rq, long long x) { upd(lq, rq, x, 1, 0, n - 1); }
  pair<long long, long long> get(int lq, int rq) {
    return get(lq, rq, 1, 0, n - 1);
  }
};

long long X;
int n, q;
long long rt[N], sums[N];
pair<int, int> up[N][2][20];

bool read() {
  if (!(cin >> X >> n))
    return false;

  for (int i = 0; i < n; ++i)
    cin >> rt[i + 1];

  return true;
}

long long sgn(int n) { return n % 2 == 0 ? -1ll : 1ll; }

long long getans(int i, long long x, long long t) {
  auto j = upper_bound(rt, rt + n + 1, t) - rt - 1;
  assert(0 <= x + sums[j] - sums[i] && x + sums[j] - sums[i] <= X);
  x += sums[j] - sums[i] + sgn(j) * (t - rt[j]);
  return max(0ll, min(x, X));
}

void solve() {
  rt[0] = 0;
  ++n;

  for (int i = 1; i < n; ++i)
    sums[i] = sums[i - 1] + sgn(i - 1) * (rt[i] - rt[i - 1]);

  segtree T(n);

  auto getup = [&T](int i, long long L, long long R) -> pair<int, int> {
    auto p = T.get(i + 1, n - 1);

    if (L <= p.first && p.second <= R)
      return {i, 0};

    int l = i + 1, r = n - 1;

    for (; l < r;) {
      auto m = (l + r) / 2;
      auto pp = T.get(i + 1, m);
      pp.first<L || pp.second> R ? r = m : l = m + 1;
    }

    auto pp = T.get(i + 1, l);
    return pp.first < L ? make_pair(l, 0) : make_pair(l, 1);
  };

  rt[n] = 1ll * MOD * MOD;
  up[n][0][0] = {n, 0};
  up[n][1][0] = {n, 1};
  up[n - 1][0][0] = {n - 1, 0};
  up[n - 1][1][0] = {n - 1, 1};

  for (int i = n - 2; i >= 0; --i) {
    auto x = sgn(i) * (rt[i + 1] - rt[i]);
    T.upd(i + 1, n - 1, x);
    up[i][0][0] = getup(i, 0, X);
    up[i][1][0] = getup(i, -X, 0);

    if (up[i][1][0].first == i)
      up[i][1][0].second = 1;
  }

  for (int i = n; i >= 0; --i)
    for (int k = 0; k < 2; ++k)
      for (int j = 1; j < 20; ++j)
        up[i][k][j] = up[up[i][k][j - 1].first][up[i][k][j - 1].second][j - 1];

  cin >> q;

  while (q-- > 0) {
    long long t, a;
    cin >> t >> a;
    auto p = getup(0, -a, X - a);

    if (rt[p.first] >= t || p.first == 0) {
      cout << getans(0, a, t) << endl;
      continue;
    }

    for (int k = 19; k >= 0; --k)
      if (rt[up[p.first][p.second][k].first] < t)
        p = up[p.first][p.second][k];

    cout << getans(p.first, p.second * X, t) << endl;
  }
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  while (read())
    solve();

  return 0;
}


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

using namespace std;

const int N = 200 * 1000 + 17;
const int MOD = 1000 * 1000 * 1000 + 7;

struct segtree {
  int n;
  vector<long long> Tmin, Tmax, U;

  segtree() {}
  segtree(int n) : n(n) {
    Tmin.resize(4 * n);
    Tmax.resize(4 * n);
    U.resize(4 * n);
  }

  void push(int v) {
    Tmin[2 * v] += U[v];
    Tmax[2 * v] += U[v];
    U[2 * v] += U[v];
    Tmin[2 * v + 1] += U[v];
    Tmax[2 * v + 1] += U[v];
    U[2 * v + 1] += U[v];
    U[v] = 0;
  }

  void upd(int lq, int rq, long long x, int v, int l, int r) {
    if (r < lq || l > rq)
      return;

    if (lq <= l && r <= rq) {
      Tmin[v] += x;
      Tmax[v] += x;
      U[v] += x;
      return;
    }

    push(v);
    auto m = (l + r) / 2;
    upd(lq, rq, x, 2 * v, l, m);
    upd(lq, rq, x, 2 * v + 1, m + 1, r);
    Tmin[v] = min(Tmin[2 * v], Tmin[2 * v + 1]);
    Tmax[v] = max(Tmax[2 * v], Tmax[2 * v + 1]);
  }

  pair<long long, long long> get(int lq, int rq, int v, int l, int r) {
    if (r < lq || l > rq)
      return {1ll * MOD * MOD, -1ll * MOD * MOD};

    if (lq <= l && r <= rq)
      return {Tmin[v], Tmax[v]};

    push(v);
    auto m = (l + r) / 2;
    auto pl = get(lq, rq, 2 * v, l, m);
    auto pr = get(lq, rq, 2 * v + 1, m + 1, r);
    return {min(pl.first, pr.first), max(pl.second, pr.second)};
  }

  void upd(int lq, int rq, long long x) { upd(lq, rq, x, 1, 0, n - 1); }
  pair<long long, long long> get(int lq, int rq) {
    return get(lq, rq, 1, 0, n - 1);
  }
};

long long X;
int n, q;
long long rt[N], sums[N];
pair<int, int> up[N][2][20];

bool read() {
  if (!(cin >> X >> n))
    return false;

  for (int i = 0; i < n; ++i)
    cin >> rt[i + 1];

  return true;
}

long long sgn(int n) { return n % 2 == 0 ? -1ll : 1ll; }

long long getans(int i, long long x, long long t) {
  auto j = upper_bound(rt, rt + n + 1, t) - rt - 1;
  x += sums[j] - sums[i] + sgn(j) * (t - rt[j]);
  return max(0ll, min(x, X));
}

void solve() {
  rt[0] = 0;
  ++n;

  for (int i = 1; i < n; ++i)
    sums[i] = sums[i - 1] + sgn(i - 1) * (rt[i] - rt[i - 1]);

  segtree T(n);

  auto getup = [&T](int i, long long L, long long R) -> pair<int, int> {
    auto p = T.get(i + 1, n - 1);

    if (L <= p.first && p.second <= R)
      return {i, 0};

    int l = i + 1, r = n - 1;

    for (; l < r;) {
      auto m = (l + r) / 2;
      auto pp = T.get(i + 1, m);
      pp.first<L || pp.second> R ? r = m : l = m + 1;
    }

    auto pp = T.get(i + 1, l);
    return pp.first < L ? make_pair(l, 0) : make_pair(l, 1);
  };

  rt[n] = 1ll * MOD * MOD;
  up[n][0][0] = {n, 0};
  up[n][1][0] = {n, 1};
  up[n - 1][0][0] = {n - 1, 0};
  up[n - 1][1][0] = {n - 1, 1};

  for (int i = n - 2; i >= 0; --i) {
    auto x = sgn(i) * (rt[i + 1] - rt[i]);
    T.upd(i + 1, n - 1, x);
    up[i][0][0] = getup(i, 0, X);
    up[i][1][0] = getup(i, -X, 0);

    if (up[i][1][0].first == i)
      up[i][1][0].second = 1;
  }

  for (int i = n; i >= 0; --i)
    for (int k = 0; k < 2; ++k)
      for (int j = 1; j < 20; ++j)
        up[i][k][j] = up[up[i][k][j - 1].first][up[i][k][j - 1].second][j - 1];

  cin >> q;

  while (q-- > 0) {
    long long t, a;
    cin >> t >> a;
    auto p = getup(0, -a, X - a);

    if (rt[p.first] >= t || p.first == 0) {
      cout << getans(0, a, t) << endl;
      continue;
    }

    for (int k = 19; k >= 0; --k)
      if (rt[up[p.first][p.second][k].first] < t)
        p = up[p.first][p.second][k];

    cout << getans(p.first, p.second * X, t) << endl;
  }
}

int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  while (read())
    solve();

  return 0;
}