Problem p03736 (C++)

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

#define MAX 200012

int n;
int q;
int A;
int B;

vector<long long int> v;

long long int dep1[MAX]; // i i+1
long long int dep2[MAX]; // i+1 i

class MIN_SEG {
public:
  vector<long long int> seg;
  vector<long long int> lazy;
  int SIZE;

private:
  void update(int b) {
    if (seg[b] != LLONG_MAX) {
      seg[b] += lazy[b];
      if (b * 2 + 2 < seg.size()) {
        lazy[b * 2 + 2] += lazy[b];
        lazy[b * 2 + 1] += lazy[b];
      }
      lazy[b] = 0;
      return;
    }
    lazy[b] = 0;
  }
  inline void add(int b, int l, int r, int ll, long long int x) {
    update(b);
    if (l <= ll && ll < r) {
      if (l + 1 == r) {
        seg[b] = min(seg[b], x);
        return;
      }
      if (l + 1 < r) {
        add(b * 2 + 1, l, (l + r) >> 1, ll, x);
        add(b * 2 + 2, (l + r) >> 1, r, ll, x);
        seg[b] = min(seg[b * 2 + 1], seg[b * 2 + 2]);
      }
    }
  }
  inline long long int query(int b, int l, int r, int ll, int rr) {
    update(b);
    if (r <= ll || rr <= l) {
      return LLONG_MAX;
    }
    if (ll <= l && r <= rr) {
      return seg[b];
    }
    return min(query(b * 2 + 1, l, (l + r) >> 1, ll, rr),
               query(b * 2 + 2, (l + r) >> 1, r, ll, rr));
  }

public:
  void append(int l, int x) { add(0, 0, SIZE, l, x); }
  long long int query(int l, int r) { return query(0, 0, SIZE, l, r); }
  void init(int s) {
    SIZE = s;
    lazy.assign(SIZE * 4, 0);
    seg.assign(SIZE * 4, LLONG_MAX);
  }
  void add_all(long long int c) { lazy[0] += c; }
};

MIN_SEG segA[2];
MIN_SEG segB[2];

int main() {
  cin >> n >> q >> A >> B;
  for (int i = 0; i < q; i++) {
    int x;
    scanf("%d", &x);
    v.push_back(x);
  }
  segA[0].init(n + 3);
  segA[1].init(n + 3);
  segB[0].init(n + 3);
  segB[1].init(n + 3);
  for (int i = 0; i < MAX; i++) {
    dep1[i] = i;
  }
  dep2[MAX - 1] = 0;
  for (int i = MAX - 2; i >= 0; i--) {
    dep2[i] = dep2[i + 1] + 1;
  }
  for (int i = 1; i <= n; i++) {
    long long int dist = abs(i - A);
    segB[0].append(i, dist + dep1[i]);
    segB[1].append(i, dist + dep2[i]);
    dist = abs(i - B);
    segA[0].append(i, dist + dep1[i]);
    segA[1].append(i, dist + dep2[i]);
  }
  for (int i = 0; i < q; i++) {
    // move A
    long long int C1 = min(segB[0].query(v[i], n + 1) - dep1[v[i]],
                           segB[1].query(1, v[i] + 1) - dep2[v[i]]);
    long long int C2 = min(segA[0].query(v[i], n + 1) - dep1[v[i]],
                           segA[1].query(1, v[i] + 1) - dep2[v[i]]);
    if (C1 < 0 || C2 < 0LL) {
      exit(1);
    }
    {{// A-> cur
      long long int cost = abs(v[i] - A);
    segA[0].add_all(cost);
    segA[1].add_all(cost);
  }
  { // somewhere -> cur
    long long int C = C1;
    segA[0].append(B, C + dep1[B]);
    segA[1].append(B, C + dep2[B]);
  }
}
// moveB
{
  { // B-> cur
    long long int cost = abs(v[i] - B);
    segB[0].add_all(cost);
    segB[1].add_all(cost);
  }
  { // somewhere -> cur
    long long int C = C2;
    segB[0].append(A, C + dep1[A]);
    segB[1].append(A, C + dep2[A]);
  }
}
A = B = v[i];
}
long long int ans = LLONG_MAX;
for (int i = 1; i <= n; i++) {
  ans = min(ans, segA[0].query(i, i + 1) - dep1[i]);
  ans = min(ans, segA[1].query(i, i + 1) - dep2[i]);
  ans = min(ans, segB[0].query(i, i + 1) - dep1[i]);
  ans = min(ans, segB[1].query(i, i + 1) - dep2[i]);
}
if (ans < 0)
  exit(1);
printf("%lld\n", ans);
return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;

#define MAX 200012

int n;
int q;
int A;
int B;

vector<long long int> v;

long long int dep1[MAX]; // i i+1
long long int dep2[MAX]; // i+1 i

class MIN_SEG {
public:
  vector<long long int> seg;
  vector<long long int> lazy;
  int SIZE;

private:
  void update(int b) {
    if (seg[b] != LLONG_MAX) {
      seg[b] += lazy[b];
      if (b * 2 + 2 < seg.size()) {
        lazy[b * 2 + 2] += lazy[b];
        lazy[b * 2 + 1] += lazy[b];
      }
      lazy[b] = 0;
      return;
    }
    lazy[b] = 0;
  }
  inline void add(int b, int l, int r, int ll, long long int x) {
    update(b);
    if (l <= ll && ll < r) {
      if (l + 1 == r) {
        seg[b] = min(seg[b], x);
        return;
      }
      if (l + 1 < r) {
        add(b * 2 + 1, l, (l + r) >> 1, ll, x);
        add(b * 2 + 2, (l + r) >> 1, r, ll, x);
        seg[b] = min(seg[b * 2 + 1], seg[b * 2 + 2]);
      }
    }
  }
  inline long long int query(int b, int l, int r, int ll, int rr) {
    update(b);
    if (r <= ll || rr <= l) {
      return LLONG_MAX;
    }
    if (ll <= l && r <= rr) {
      return seg[b];
    }
    return min(query(b * 2 + 1, l, (l + r) >> 1, ll, rr),
               query(b * 2 + 2, (l + r) >> 1, r, ll, rr));
  }

public:
  void append(int l, long long int x) { add(0, 0, SIZE, l, x); }
  long long int query(int l, int r) { return query(0, 0, SIZE, l, r); }
  void init(int s) {
    SIZE = s;
    lazy.assign(SIZE * 4, 0);
    seg.assign(SIZE * 4, LLONG_MAX);
  }
  void add_all(long long int c) { lazy[0] += c; }
};

MIN_SEG segA[2];
MIN_SEG segB[2];

int main() {
  cin >> n >> q >> A >> B;
  for (int i = 0; i < q; i++) {
    int x;
    scanf("%d", &x);
    v.push_back(x);
  }
  segA[0].init(n + 3);
  segA[1].init(n + 3);
  segB[0].init(n + 3);
  segB[1].init(n + 3);
  for (int i = 0; i < MAX; i++) {
    dep1[i] = i;
  }
  dep2[MAX - 1] = 0;
  for (int i = MAX - 2; i >= 0; i--) {
    dep2[i] = dep2[i + 1] + 1;
  }
  for (int i = 1; i <= n; i++) {
    long long int dist = abs(i - A);
    segB[0].append(i, dist + dep1[i]);
    segB[1].append(i, dist + dep2[i]);
    dist = abs(i - B);
    segA[0].append(i, dist + dep1[i]);
    segA[1].append(i, dist + dep2[i]);
  }
  for (int i = 0; i < q; i++) {
    // move A
    long long int C1 = min(segB[0].query(v[i], n + 1) - dep1[v[i]],
                           segB[1].query(1, v[i] + 1) - dep2[v[i]]);
    long long int C2 = min(segA[0].query(v[i], n + 1) - dep1[v[i]],
                           segA[1].query(1, v[i] + 1) - dep2[v[i]]);
    if (C1 < 0 || C2 < 0LL) {
      exit(1);
    }
    {{// A-> cur
      long long int cost = abs(v[i] - A);
    segA[0].add_all(cost);
    segA[1].add_all(cost);
  }
  { // somewhere -> cur
    long long int C = C1;
    segA[0].append(B, C + dep1[B]);
    segA[1].append(B, C + dep2[B]);
  }
}
// moveB
{
  { // B-> cur
    long long int cost = abs(v[i] - B);
    segB[0].add_all(cost);
    segB[1].add_all(cost);
  }
  { // somewhere -> cur
    long long int C = C2;
    segB[0].append(A, C + dep1[A]);
    segB[1].append(A, C + dep2[A]);
  }
}
A = B = v[i];
}
long long int ans = LLONG_MAX;
for (int i = 1; i <= n; i++) {
  ans = min(ans, segA[0].query(i, i + 1) - dep1[i]);
  ans = min(ans, segA[1].query(i, i + 1) - dep2[i]);
  ans = min(ans, segB[0].query(i, i + 1) - dep1[i]);
  ans = min(ans, segB[1].query(i, i + 1) - dep2[i]);
}
if (ans < 0)
  exit(1);
printf("%lld\n", ans);
return 0;
}