Problem p03736 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll, ll> P;
typedef pair<int, int> pii;
typedef vector<P> vpl;
typedef tuple<ll, ll, ll> tapu;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1 << 30;
const ll linf = 1LL << 62;
const int MAX = 1020000;
ll dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};
ll dx[8] = {0, 0, 1, -1, 1, -1, -1, 1};
const double pi = acos(-1);
const double eps = 1e-7;
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T> inline void print(T &a) {
  rep(i, a.size()) cout << a[i] << " ";
  cout << "\n";
}
template <typename T1, typename T2> inline void print2(T1 a, T2 b) {
  cout << a << " " << b << "\n";
}
template <typename T1, typename T2, typename T3>
inline void print3(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << "\n";
}
ll pcount(ll x) { return __builtin_popcountll(x); }
const int mod = 1e9 + 7;
// const int mod = 998244353;

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  int sz, height;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &M1,
                  const OperatorMonoid OM0)
      : f(f), g(g), h(h), M1(M1), OM0(OM0) {
    sz = 1;
    height = 0;
    while (sz < n)
      sz <<= 1, height++;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  inline void propagate(int k) {
    if (lazy[k] != OM0) {
      lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      data[k] = reflect(k);
      lazy[k] = OM0;
    }
  }

  inline Monoid reflect(int k) {
    return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]);
  }

  inline void recalc(int k) {
    while (k >>= 1)
      data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1));
  }

  inline void thrust(int k) {
    for (int i = height; i > 0; i--)
      propagate(k >> i);
  }

  void update(int a, int b, const OperatorMonoid &x) {
    thrust(a += sz);
    thrust(b += sz - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), ++l;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }

  Monoid query(int a, int b) {
    thrust(a += sz);
    thrust(b += sz - 1);
    Monoid L = M1, R = M1;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        L = f(L, reflect(l++));
      if (r & 1)
        R = f(reflect(--r), R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) { return query(k, k + 1); }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      propagate(a);
      Monoid nxt =
          type ? f(reflect(2 * a + type), M) : f(M, reflect(2 * a + type));
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, reflect(1))))
        return find_subtree(1, check, L, false);
      return -1;
    }
    thrust(a + sz);
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, reflect(a));
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(reflect(1), R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    thrust(b + sz - 1);
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(reflect(--b), R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

auto f = [](ll a, ll b) { return min(a, b); };
auto g = [](ll a, ll b) { return a + b; };
auto h = [](ll a, ll b) { return a + b; };

int main() {
  int n, q;
  cin >> n >> q;
  int y;
  vl x(n + 1);
  cin >> x[0] >> y;
  x[0]--;
  y--;
  vector<LazySegmentTree<ll>> seg1(2, LazySegmentTree<ll>(n, f, g, h, linf, 0));
  vector<LazySegmentTree<ll>> seg2(2, LazySegmentTree<ll>(n, f, g, h, linf, 0));
  rep(i, 2) rep(j, n) {
    seg1[i].update(j, j + 1, (1LL << 40) - linf);
    seg2[i].update(j, j + 1, (1LL << 40) - linf);
  }
  seg1[0].update(y, y + 1, -y - (1LL << 40));
  seg2[0].update(y, y + 1, y - (1LL << 40));
  for (int i = 1; i <= q; i++) {
    cin >> x[i];
    x[i]--;
    vl mn(2, linf);
    rep(j, 2) {
      chmin(mn[j], seg1[j].query(0, x[i]) + x[i]);
      chmin(mn[j], seg2[j].query(x[i], n) - x[i]);
    }
    rep(j, 2) {
      seg1[j].update(0, n, abs(x[i] - x[i - 1]));
      seg2[j].update(0, n, abs(x[i] - x[i - 1]));
      ll t = seg1[j].query(x[i - 1], x[i - 1] + 1) + x[i - 1];
      if (t > mn[j ^ 1]) {
        seg1[j].update(x[i - 1], x[i - 1] + 1, mn[j ^ 1] - t);
        seg2[j].update(x[i - 1], x[i - 1] + 1,
                       mn[j ^ 1] + x[i - 1] -
                           seg2[j].query(x[i - 1], x[i - 1] + 1));
      }
    }
  }
  ll ans = linf;
  rep(i, 2) { rep(j, n) chmin(ans, seg1[i].query(j, j + 1) + j); }
  cout << ans << "\n";
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll, ll> P;
typedef pair<int, int> pii;
typedef vector<P> vpl;
typedef tuple<ll, ll, ll> tapu;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1 << 30;
const ll linf = 1LL << 62;
const int MAX = 1020000;
ll dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};
ll dx[8] = {0, 0, 1, -1, 1, -1, -1, 1};
const double pi = acos(-1);
const double eps = 1e-7;
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T> inline void print(T &a) {
  rep(i, a.size()) cout << a[i] << " ";
  cout << "\n";
}
template <typename T1, typename T2> inline void print2(T1 a, T2 b) {
  cout << a << " " << b << "\n";
}
template <typename T1, typename T2, typename T3>
inline void print3(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << "\n";
}
ll pcount(ll x) { return __builtin_popcountll(x); }
const int mod = 1e9 + 7;
// const int mod = 998244353;

template <typename Monoid, typename OperatorMonoid = Monoid>
struct LazySegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  using G = function<Monoid(Monoid, OperatorMonoid)>;
  using H = function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;

  int sz, height;
  vector<Monoid> data;
  vector<OperatorMonoid> lazy;
  const F f;
  const G g;
  const H h;
  const Monoid M1;
  const OperatorMonoid OM0;

  LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &M1,
                  const OperatorMonoid OM0)
      : f(f), g(g), h(h), M1(M1), OM0(OM0) {
    sz = 1;
    height = 0;
    while (sz < n)
      sz <<= 1, height++;
    data.assign(2 * sz, M1);
    lazy.assign(2 * sz, OM0);
  }

  void set(int k, const Monoid &x) { data[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      data[k] = f(data[2 * k + 0], data[2 * k + 1]);
    }
  }

  inline void propagate(int k) {
    if (lazy[k] != OM0) {
      lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      data[k] = reflect(k);
      lazy[k] = OM0;
    }
  }

  inline Monoid reflect(int k) {
    return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]);
  }

  inline void recalc(int k) {
    while (k >>= 1)
      data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1));
  }

  inline void thrust(int k) {
    for (int i = height; i > 0; i--)
      propagate(k >> i);
  }

  void update(int a, int b, const OperatorMonoid &x) {
    thrust(a += sz);
    thrust(b += sz - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), ++l;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }

  Monoid query(int a, int b) {
    thrust(a += sz);
    thrust(b += sz - 1);
    Monoid L = M1, R = M1;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        L = f(L, reflect(l++));
      if (r & 1)
        R = f(reflect(--r), R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) { return query(k, k + 1); }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      propagate(a);
      Monoid nxt =
          type ? f(reflect(2 * a + type), M) : f(M, reflect(2 * a + type));
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, reflect(1))))
        return find_subtree(1, check, L, false);
      return -1;
    }
    thrust(a + sz);
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, reflect(a));
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(reflect(1), R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    thrust(b + sz - 1);
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(reflect(--b), R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

auto f = [](ll a, ll b) { return min(a, b); };
auto g = [](ll a, ll b) { return a + b; };
auto h = [](ll a, ll b) { return a + b; };

int main() {
  int n, q;
  cin >> n >> q;
  int y;
  vl x(q + 1);
  cin >> x[0] >> y;
  x[0]--;
  y--;
  vector<LazySegmentTree<ll>> seg1(2, LazySegmentTree<ll>(n, f, g, h, linf, 0));
  vector<LazySegmentTree<ll>> seg2(2, LazySegmentTree<ll>(n, f, g, h, linf, 0));
  rep(i, 2) rep(j, n) {
    seg1[i].update(j, j + 1, (1LL << 40) - linf);
    seg2[i].update(j, j + 1, (1LL << 40) - linf);
  }
  seg1[0].update(y, y + 1, -y - (1LL << 40));
  seg2[0].update(y, y + 1, y - (1LL << 40));
  for (int i = 1; i <= q; i++) {
    cin >> x[i];
    x[i]--;
    vl mn(2, linf);
    rep(j, 2) {
      chmin(mn[j], seg1[j].query(0, x[i]) + x[i]);
      chmin(mn[j], seg2[j].query(x[i], n) - x[i]);
    }
    rep(j, 2) {
      seg1[j].update(0, n, abs(x[i] - x[i - 1]));
      seg2[j].update(0, n, abs(x[i] - x[i - 1]));
      ll t = seg1[j].query(x[i - 1], x[i - 1] + 1) + x[i - 1];
      if (t > mn[j ^ 1]) {
        seg1[j].update(x[i - 1], x[i - 1] + 1, mn[j ^ 1] - t);
        seg2[j].update(x[i - 1], x[i - 1] + 1,
                       mn[j ^ 1] + x[i - 1] -
                           seg2[j].query(x[i - 1], x[i - 1] + 1));
      }
    }
  }
  ll ans = linf;
  rep(i, 2) { rep(j, n) chmin(ans, seg1[i].query(j, j + 1) + j); }
  cout << ans << "\n";
}