Problem p03790 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
// #define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template <class T> void read(T &res) {
  res = 0;
  T f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    res = res * 10 + c - '0';
    c = getchar();
  }
  res *= f;
}
template <class T> void out(T x) {
  if (x < 0) {
    x = -x;
    putchar('-');
  }
  if (x >= 10) {
    out(x / 10);
  }
  putchar('0' + x % 10);
}

int N;
int64 K, A[MAXN], sum[MAXN];
int B[MAXN], tot;
int64 L[MAXN], R[MAXN], dpL[MAXN], dpR[MAXN], val[MAXN];
struct node {
  int l, r;
  int mx, lz;
} tr[MAXN * 2];
int id;
void update(int u) {
  if (!id)
    tr[u].mx = min(tr[u << 1].mx, tr[u << 1 | 1].mx);
  else
    tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);
}
void addlz(int u, int v) {
  tr[u].lz = v;
  tr[u].mx = v;
}
void pushdown(int u) {
  if (tr[u].lz) {
    addlz(u << 1, tr[u].lz);
    addlz(u << 1 | 1, tr[u].lz);
    tr[u].lz = 0;
  }
}
void build(int u, int l, int r, int v) {
  tr[u].l = l;
  tr[u].r = r;
  tr[u].lz = 0;
  if (l == r) {
    tr[u].mx = v;
    return;
  }
  int mid = (l + r) >> 1;
  build(u << 1, l, mid, v);
  build(u << 1 | 1, mid + 1, r, v);
  update(u);
}
void cover(int u, int l, int r, int v) {
  if (l > r)
    return;
  if (tr[u].l == l && tr[u].r == r) {
    addlz(u, v);
    return;
  }
  pushdown(u);
  int mid = (tr[u].l + tr[u].r) >> 1;
  if (r <= mid)
    cover(u << 1, l, r, v);
  else if (l > mid)
    cover(u << 1 | 1, l, r, v);
  else {
    cover(u << 1, l, mid, v);
    cover(u << 1 | 1, mid + 1, r, v);
  }
  update(u);
}
int query(int u, int l, int r) {
  if (l > r)
    return N + 1;
  if (tr[u].l == l && tr[u].r == r)
    return tr[u].mx;
  pushdown(u);
  int mid = (tr[u].l + tr[u].r) >> 1;
  if (r <= mid)
    return query(u << 1, l, r);
  else if (l > mid)
    return query(u << 1 | 1, l, r);
  else {
    if (!id)
      return min(query(u << 1, l, mid), query(u << 1 | 1, mid + 1, r));
    else
      return max(query(u << 1, l, mid), query(u << 1 | 1, mid + 1, r));
  }
}
int64 dist(int64 A, int64 B) {
  if (B >= A)
    return B - A;
  else
    return K - (A - B);
}
void Solve() {
  read(N);
  read(K);
  for (int i = 1; i <= N; ++i) {
    read(A[i]);
    read(B[i]);
    sum[i] = sum[i - 1] + A[i];
    if (B[i] == 1) {
      if (2 * A[i] > K) {
        puts("-1");
        return;
      }
      L[i] = (-2 * sum[i - 1] % K + K) % K;
      R[i] = (-2 * sum[i] % K + K) % K;
      val[++tot] = L[i];
      val[++tot] = R[i];
    }
  }

  sort(val + 1, val + tot + 1);
  tot = unique(val + 1, val + tot + 1) - val - 1;
  id = 0;
  build(1, 1, tot, N + 1);
  for (int i = N; i >= 1; --i) {
    if (B[i] == 1) {
      int l = lower_bound(val + 1, val + tot + 1, L[i]) - val;
      int r = lower_bound(val + 1, val + tot + 1, R[i]) - val;
      int t = query(1, l, l);
      if (t == N + 1)
        dpL[i] = 0;
      else
        dpL[i] = min(dpL[t] + dist(L[i], L[t]), dpR[t] + dist(L[i], R[t]));
      t = query(1, r, r);
      if (t == N + 1)
        dpR[i] = 0;
      else
        dpR[i] = min(dpR[t] + dist(R[i], R[t]), dpL[t] + dist(R[i], L[t]));
      if (l <= r) {
        cover(1, 1, l - 1, i);
        cover(1, r + 1, tot, i);
      } else {
        cover(1, r + 1, l - 1, i);
      }
    }
  }
  id = 1;
  build(1, 1, tot, 0);
  int64 ans = 1e18;
  for (int i = 1; i <= N; ++i) {
    if (B[i] == 1) {
      int l = lower_bound(val + 1, val + tot + 1, L[i]) - val;
      int r = lower_bound(val + 1, val + tot + 1, R[i]) - val;
      int t = query(1, l, l);
      if (t == 0)
        ans = min(ans, dpL[i]);
      t = query(1, r, r);
      if (t == 0)
        ans = min(ans, dpR[i]);
      if (l <= r) {
        cover(1, 1, l - 1, i);
        cover(1, r + 1, tot, i);
      } else {
        cover(1, r + 1, l - 1, i);
      }
    }
  }
  ans += 2 * sum[N];
  out(ans);
  enter;
}
int main() {
#ifdef ivorysi
  freopen("f1.in", "r", stdin);
#endif
  Solve();
}


Fixed submission:
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
// #define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template <class T> void read(T &res) {
  res = 0;
  T f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    res = res * 10 + c - '0';
    c = getchar();
  }
  res *= f;
}
template <class T> void out(T x) {
  if (x < 0) {
    x = -x;
    putchar('-');
  }
  if (x >= 10) {
    out(x / 10);
  }
  putchar('0' + x % 10);
}

int N;
int64 K, A[MAXN], sum[MAXN];
int B[MAXN], tot;
int64 L[MAXN], R[MAXN], dpL[MAXN], dpR[MAXN], val[MAXN];
struct node {
  int l, r;
  int mx, lz;
} tr[MAXN * 4];
int id;
void update(int u) {
  if (!id)
    tr[u].mx = min(tr[u << 1].mx, tr[u << 1 | 1].mx);
  else
    tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);
}
void addlz(int u, int v) {
  tr[u].lz = v;
  tr[u].mx = v;
}
void pushdown(int u) {
  if (tr[u].lz) {
    addlz(u << 1, tr[u].lz);
    addlz(u << 1 | 1, tr[u].lz);
    tr[u].lz = 0;
  }
}
void build(int u, int l, int r, int v) {
  tr[u].l = l;
  tr[u].r = r;
  tr[u].lz = 0;
  if (l == r) {
    tr[u].mx = v;
    return;
  }
  int mid = (l + r) >> 1;
  build(u << 1, l, mid, v);
  build(u << 1 | 1, mid + 1, r, v);
  update(u);
}
void cover(int u, int l, int r, int v) {
  if (l > r)
    return;
  if (tr[u].l == l && tr[u].r == r) {
    addlz(u, v);
    return;
  }
  pushdown(u);
  int mid = (tr[u].l + tr[u].r) >> 1;
  if (r <= mid)
    cover(u << 1, l, r, v);
  else if (l > mid)
    cover(u << 1 | 1, l, r, v);
  else {
    cover(u << 1, l, mid, v);
    cover(u << 1 | 1, mid + 1, r, v);
  }
  update(u);
}
int query(int u, int l, int r) {
  if (l > r)
    return N + 1;
  if (tr[u].l == l && tr[u].r == r)
    return tr[u].mx;
  pushdown(u);
  int mid = (tr[u].l + tr[u].r) >> 1;
  if (r <= mid)
    return query(u << 1, l, r);
  else if (l > mid)
    return query(u << 1 | 1, l, r);
  else {
    if (!id)
      return min(query(u << 1, l, mid), query(u << 1 | 1, mid + 1, r));
    else
      return max(query(u << 1, l, mid), query(u << 1 | 1, mid + 1, r));
  }
}
int64 dist(int64 A, int64 B) {
  if (B >= A)
    return B - A;
  else
    return K - (A - B);
}
void Solve() {
  read(N);
  read(K);
  for (int i = 1; i <= N; ++i) {
    read(A[i]);
    read(B[i]);
    sum[i] = sum[i - 1] + A[i];
    if (B[i] == 1) {
      if (2 * A[i] > K) {
        puts("-1");
        return;
      }
      L[i] = (-2 * sum[i - 1] % K + K) % K;
      R[i] = (-2 * sum[i] % K + K) % K;
      val[++tot] = L[i];
      val[++tot] = R[i];
    }
  }

  sort(val + 1, val + tot + 1);
  tot = unique(val + 1, val + tot + 1) - val - 1;
  id = 0;
  build(1, 1, tot, N + 1);
  for (int i = N; i >= 1; --i) {
    if (B[i] == 1) {
      int l = lower_bound(val + 1, val + tot + 1, L[i]) - val;
      int r = lower_bound(val + 1, val + tot + 1, R[i]) - val;
      int t = query(1, l, l);
      if (t == N + 1)
        dpL[i] = 0;
      else
        dpL[i] = min(dpL[t] + dist(L[i], L[t]), dpR[t] + dist(L[i], R[t]));
      t = query(1, r, r);
      if (t == N + 1)
        dpR[i] = 0;
      else
        dpR[i] = min(dpR[t] + dist(R[i], R[t]), dpL[t] + dist(R[i], L[t]));
      if (l <= r) {
        cover(1, 1, l - 1, i);
        cover(1, r + 1, tot, i);
      } else {
        cover(1, r + 1, l - 1, i);
      }
    }
  }
  id = 1;
  build(1, 1, tot, 0);
  int64 ans = 1e18;
  for (int i = 1; i <= N; ++i) {
    if (B[i] == 1) {
      int l = lower_bound(val + 1, val + tot + 1, L[i]) - val;
      int r = lower_bound(val + 1, val + tot + 1, R[i]) - val;
      int t = query(1, l, l);
      if (t == 0)
        ans = min(ans, dpL[i]);
      t = query(1, r, r);
      if (t == 0)
        ans = min(ans, dpR[i]);
      if (l <= r) {
        cover(1, 1, l - 1, i);
        cover(1, r + 1, tot, i);
      } else {
        cover(1, r + 1, l - 1, i);
      }
    }
  }
  ans += 2 * sum[N];
  out(ans);
  enter;
}
int main() {
#ifdef ivorysi
  freopen("f1.in", "r", stdin);
#endif
  Solve();
}