Problem p03790 (C++)

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

const int maxn = 1e5 + 10;
const int maxnd = 5e6 + 10;
const LL INF = 1e16;

int n, b[maxn];
LL k, a[maxn];

namespace SegTree {
LL mn[maxn], _mn[maxn], mem[maxn];
int totnd, root, lc[maxnd], rc[maxnd];
#define mid ((s + t) >> 1)

void init() {
  totnd = root = 1;
  memset(mem, -1, sizeof(mem));
}

inline void pushdown(int nd, int s, int t) {
  if (!lc[nd])
    lc[nd] = ++totnd;
  if (!rc[nd])
    rc[nd] = ++totnd;
  mn[lc[nd]] = mn[rc[nd]] = mem[nd];
  _mn[lc[nd]] = mem[nd] - mid;
  _mn[rc[nd]] = mem[nd] - t;
  mem[lc[nd]] = mem[rc[nd]] = mem[nd];
  mem[nd] = -1;
}

LL query(int &nd, int s, int t, int l, int r) {
  if (!nd)
    nd = ++totnd;
  if (l <= s && t <= r)
    return _mn[nd];
  if (mem[nd] != -1)
    pushdown(nd, s, t);
  LL Ans = INF;
  if (l <= mid)
    Ans = min(Ans, query(lc[nd], s, mid, l, r));
  if (r > mid)
    Ans = min(Ans, query(rc[nd], mid + 1, t, l, r));
  mn[nd] = min(mn[lc[nd]], mn[rc[nd]]);
  _mn[nd] = min(_mn[lc[nd]], _mn[rc[nd]]);
  return Ans;
}

void checkmin(int &nd, int s, int t, int id, LL val) {
  if (!nd)
    nd = ++totnd;
  if (s == t) {
    mn[nd] = min(mn[nd], val);
    _mn[nd] = mn[nd] - s;
    return;
  }
  if (mem[nd] != -1)
    pushdown(nd, s, t);
  if (id <= mid)
    checkmin(lc[nd], s, mid, id, val);
  else
    checkmin(rc[nd], mid + 1, t, id, val);
  mn[nd] = min(mn[lc[nd]], mn[rc[nd]]);
  _mn[nd] = min(_mn[lc[nd]], _mn[rc[nd]]);
}

void memset(int &nd, int s, int t, int l, int r, LL val) {
  if (!nd)
    nd = ++totnd;
  if (l <= s && t <= r) {
    mn[nd] = val;
    _mn[nd] = mn[nd] - t;
    mem[nd] = val;
    return;
  }
  if (mem[nd] != -1)
    pushdown(nd, s, t);
  if (l <= mid)
    memset(lc[nd], s, mid, l, r, val);
  if (r > mid)
    memset(rc[nd], mid + 1, t, l, r, val);
  mn[nd] = min(mn[lc[nd]], mn[rc[nd]]);
  _mn[nd] = min(_mn[lc[nd]], _mn[rc[nd]]);
}
}; // namespace SegTree

int main() {
#ifdef h10
  freopen("F.in", "r", stdin);
  freopen("F.out", "w", stdout);
#endif
  int i;
  scanf("%d%lld", &n, &k);
  for (i = 1; i <= n; i++) {
    scanf("%lld%d", &a[i], &b[i]);
    if (b[i] == 1 && 2 * a[i] > k) {
      puts("-1");
      return 0;
    }
    a[i] += a[i - 1];
  }
  SegTree::init();
  SegTree::memset(SegTree::root, 0, k - 1, 0, k - 1, 0);
  for (i = 1; i <= n; i++)
    if (b[i] == 1) {
      int L = k - 2ll * a[i - 1] % k, R = k - 2ll * a[i] % k;
      L %= k;
      R %= k;
      LL Ans = SegTree::query(SegTree::root, 0, k - 1, 0, L) + L;
      Ans = min(Ans, SegTree::query(SegTree::root, 0, k - 1, L, k - 1) + k + L);
      SegTree::checkmin(SegTree::root, 0, k - 1, L, Ans);
      if (L <= R) {
        if (0 < L)
          SegTree::memset(SegTree::root, 0, k - 1, 0, L - 1, INF);
        if (R < k - 1)
          SegTree::memset(SegTree::root, 0, k - 1, R + 1, k - 1, INF);
      } else if (R + 1 <= L - 1)
        SegTree::memset(SegTree::root, 0, k - 1, R + 1, L - 1, INF);
    }
  printf("%lld\n", a[n] + a[n] + SegTree::mn[SegTree::root]);
}


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

const int maxn = 1e5 + 10;
const int maxnd = 5e6 + 10;
const LL INF = 1e16;

int n, b[maxn];
LL k, a[maxn];

namespace SegTree {
LL mn[maxnd], _mn[maxnd], mem[maxnd];
int totnd, root, lc[maxnd], rc[maxnd];
#define mid ((s + t) >> 1)

void init() {
  totnd = root = 1;
  memset(mem, -1, sizeof(mem));
}

inline void pushdown(int nd, int s, int t) {
  if (!lc[nd])
    lc[nd] = ++totnd;
  if (!rc[nd])
    rc[nd] = ++totnd;
  mn[lc[nd]] = mn[rc[nd]] = mem[nd];
  _mn[lc[nd]] = mem[nd] - mid;
  _mn[rc[nd]] = mem[nd] - t;
  mem[lc[nd]] = mem[rc[nd]] = mem[nd];
  mem[nd] = -1;
}

LL query(int &nd, int s, int t, int l, int r) {
  if (!nd)
    nd = ++totnd;
  if (l <= s && t <= r)
    return _mn[nd];
  if (mem[nd] != -1)
    pushdown(nd, s, t);
  LL Ans = INF;
  if (l <= mid)
    Ans = min(Ans, query(lc[nd], s, mid, l, r));
  if (r > mid)
    Ans = min(Ans, query(rc[nd], mid + 1, t, l, r));
  mn[nd] = min(mn[lc[nd]], mn[rc[nd]]);
  _mn[nd] = min(_mn[lc[nd]], _mn[rc[nd]]);
  return Ans;
}

void checkmin(int &nd, int s, int t, int id, LL val) {
  if (!nd)
    nd = ++totnd;
  if (s == t) {
    mn[nd] = min(mn[nd], val);
    _mn[nd] = mn[nd] - s;
    return;
  }
  if (mem[nd] != -1)
    pushdown(nd, s, t);
  if (id <= mid)
    checkmin(lc[nd], s, mid, id, val);
  else
    checkmin(rc[nd], mid + 1, t, id, val);
  mn[nd] = min(mn[lc[nd]], mn[rc[nd]]);
  _mn[nd] = min(_mn[lc[nd]], _mn[rc[nd]]);
}

void memset(int &nd, int s, int t, int l, int r, LL val) {
  if (!nd)
    nd = ++totnd;
  if (l <= s && t <= r) {
    mn[nd] = val;
    _mn[nd] = mn[nd] - t;
    mem[nd] = val;
    return;
  }
  if (mem[nd] != -1)
    pushdown(nd, s, t);
  if (l <= mid)
    memset(lc[nd], s, mid, l, r, val);
  if (r > mid)
    memset(rc[nd], mid + 1, t, l, r, val);
  mn[nd] = min(mn[lc[nd]], mn[rc[nd]]);
  _mn[nd] = min(_mn[lc[nd]], _mn[rc[nd]]);
}
}; // namespace SegTree

int main() {
#ifdef h10
  freopen("F.in", "r", stdin);
  freopen("F.out", "w", stdout);
#endif
  int i;
  scanf("%d%lld", &n, &k);
  for (i = 1; i <= n; i++) {
    scanf("%lld%d", &a[i], &b[i]);
    if (b[i] == 1 && 2 * a[i] > k) {
      puts("-1");
      return 0;
    }
    a[i] += a[i - 1];
  }
  SegTree::init();
  SegTree::memset(SegTree::root, 0, k - 1, 0, k - 1, 0);
  for (i = 1; i <= n; i++)
    if (b[i] == 1) {
      int L = k - 2ll * a[i - 1] % k, R = k - 2ll * a[i] % k;
      L %= k;
      R %= k;
      LL Ans = SegTree::query(SegTree::root, 0, k - 1, 0, L) + L;
      Ans = min(Ans, SegTree::query(SegTree::root, 0, k - 1, L, k - 1) + k + L);
      SegTree::checkmin(SegTree::root, 0, k - 1, L, Ans);
      if (L <= R) {
        if (0 < L)
          SegTree::memset(SegTree::root, 0, k - 1, 0, L - 1, INF);
        if (R < k - 1)
          SegTree::memset(SegTree::root, 0, k - 1, R + 1, k - 1, INF);
      } else if (R + 1 <= L - 1)
        SegTree::memset(SegTree::root, 0, k - 1, R + 1, L - 1, INF);
    }
  printf("%lld\n", a[n] + a[n] + SegTree::mn[SegTree::root]);
}