Problem p03736 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define debug(x)                                                               \
  { cout << (#x) << " " << x << endl; }
using namespace std;
typedef long long LL;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!(ch >= '0' && ch <= '9')) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + (ch - '0');
    ch = getchar();
  }
  return x * f;
}

const int N = 200005;
const LL INF = 100000000007LL;

int n, q, b;
int x[N];
LL dp[3][N], tag[N];

inline void pushup(int x) {
  rep(i, 0, 2) dp[i][x] = min(dp[i][x << 1], dp[i][x << 1 | 1]);
}

inline void pushdown(int x) {
  if (tag[x]) {
    tag[x << 1] += tag[x];
    tag[x << 1 | 1] += tag[x];
    rep(i, 0, 2) dp[i][x << 1] += tag[x], dp[i][x << 1 | 1] += tag[x];
    tag[x] = 0;
  }
}

inline void build(int x, int l, int r) {
  if (l == r) {
    rep(i, 0, 2) dp[i][x] = INF;
    tag[x] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
  pushup(x);
}

inline void change(int x, int l, int r, int p, LL val) {
  if (l == r) {
    rep(i, 0, 2) dp[i][x] = val;
    dp[1][x] -= l;
    dp[2][x] += l;
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(x);
  if (p <= mid)
    change(x << 1, l, mid, p, val);
  else
    change(x << 1 | 1, mid + 1, r, p, val);
  pushup(x);
}

inline LL query(int x, int l, int r, int ll, int rr, int tp) {
  if (r < ll || l > rr)
    return INF;
  if (l >= ll && r <= rr)
    return dp[tp][x];
  int mid = (l + r) >> 1;
  pushdown(x);
  return min(query(x << 1, l, mid, ll, rr, tp),
             query(x << 1 | 1, mid + 1, r, ll, rr, tp));
}

int main() {

#ifndef ONLINE_JUDGE
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
#endif

  n = read(), q = read(), x[0] = read(), b = read();
  rep(i, 1, q) x[i] = read();
  build(1, 1, n);
  change(1, 1, n, b, 0);
  rep(i, 1, q) {
    LL t1 = query(1, 1, n, 1, x[i], 1) + x[i],
       t2 = query(1, 1, n, x[i], n, 2) - x[i];
    LL tmp = abs(x[i] - x[i - 1]);
    rep(i, 0, 2) dp[i][1] += tmp;
    tag[1] += tmp;
    change(1, 1, n, x[i - 1], min(t1, t2));
  }
  printf("%lld\n", dp[0][1]);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define debug(x)                                                               \
  { cout << (#x) << " " << x << endl; }
using namespace std;
typedef long long LL;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!(ch >= '0' && ch <= '9')) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + (ch - '0');
    ch = getchar();
  }
  return x * f;
}

const int N = 200005;
const LL INF = 100000000007LL;

int n, q, b;
int x[N << 2];
LL dp[3][N << 2], tag[N << 2];

inline void pushup(int x) {
  rep(i, 0, 2) dp[i][x] = min(dp[i][x << 1], dp[i][x << 1 | 1]);
}

inline void pushdown(int x) {
  if (tag[x]) {
    tag[x << 1] += tag[x];
    tag[x << 1 | 1] += tag[x];
    rep(i, 0, 2) dp[i][x << 1] += tag[x], dp[i][x << 1 | 1] += tag[x];
    tag[x] = 0;
  }
}

inline void build(int x, int l, int r) {
  if (l == r) {
    rep(i, 0, 2) dp[i][x] = INF;
    tag[x] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
  pushup(x);
}

inline void change(int x, int l, int r, int p, LL val) {
  if (l == r) {
    rep(i, 0, 2) dp[i][x] = val;
    dp[1][x] -= l;
    dp[2][x] += l;
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(x);
  if (p <= mid)
    change(x << 1, l, mid, p, val);
  else
    change(x << 1 | 1, mid + 1, r, p, val);
  pushup(x);
}

inline LL query(int x, int l, int r, int ll, int rr, int tp) {
  if (r < ll || l > rr)
    return INF;
  if (l >= ll && r <= rr)
    return dp[tp][x];
  int mid = (l + r) >> 1;
  pushdown(x);
  return min(query(x << 1, l, mid, ll, rr, tp),
             query(x << 1 | 1, mid + 1, r, ll, rr, tp));
}

int main() {

#ifndef ONLINE_JUDGE
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
#endif

  n = read(), q = read(), x[0] = read(), b = read();
  rep(i, 1, q) x[i] = read();
  build(1, 1, n);
  change(1, 1, n, b, 0);
  rep(i, 1, q) {
    LL t1 = query(1, 1, n, 1, x[i], 1) + x[i],
       t2 = query(1, 1, n, x[i], n, 2) - x[i];
    LL tmp = abs(x[i] - x[i - 1]);
    rep(i, 0, 2) dp[i][1] += tmp;
    tag[1] += tmp;
    change(1, 1, n, x[i - 1], min(t1, t2));
  }
  printf("%lld\n", dp[0][1]);
  return 0;
}