Problem p03736 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define ll long long
#define MAX 200200
#define lson (now << 1)
#define rson (now << 1 | 1)
inline int read() {
  int x = 0;
  bool t = false;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-')
    ch = getchar();
  if (ch == '-')
    t = true, ch = getchar();
  while (ch <= '9' && ch >= '0')
    x = x * 10 + ch - 48, ch = getchar();
  return t ? -x : x;
}
int n, Q, A, B, a[MAX];
ll f[MAX];
struct SegMentTree {
  ll t[MAX << 2], tag[MAX << 2], a[MAX];
  void pushup(int now) { t[now] = min(t[lson], t[rson]); }
  void Build(int now, int l, int r) {
    if (l == r) {
      t[now] = f[l] + a[l];
      return;
    }
    int mid = (l + r) >> 1;
    tag[now] = 0;
    Build(lson, l, mid);
    Build(rson, mid + 1, r);
    pushup(now);
  }
  void puttag(int now, ll w) {
    t[now] += w;
    tag[now] += w;
  }
  void pushdown(int now) {
    if (!tag[now])
      return;
    puttag(lson, tag[now]);
    puttag(rson, tag[now]);
    tag[now] = 0;
  }
  void Modify(int now, int l, int r, int p, ll w) {
    if (l == r) {
      t[now] = min(t[now], w);
      return;
    }
    int mid = (l + r) >> 1;
    pushdown(now);
    if (p <= mid)
      Modify(lson, l, mid, p, w);
    else
      Modify(rson, mid + 1, r, p, w);
    pushup(now);
  }
  void Modify(int now, int l, int r, int L, int R, int w) {
    if (L <= l && r <= R) {
      puttag(now, w);
      return;
    }
    int mid = (l + r) >> 1;
    pushdown(now);
    if (L <= mid)
      Modify(lson, l, mid, L, R, w);
    if (R > mid)
      Modify(rson, mid + 1, r, L, R, w);
    pushup(now);
  }
  ll Query(int now, int l, int r, int L, int R) {
    if (L <= l && r <= R)
      return t[now];
    int mid = (l + r) >> 1;
    ll ret = 4e18;
    pushdown(now);
    if (L <= mid)
      ret = min(ret, Query(lson, l, mid, L, R));
    if (R > mid)
      ret = min(ret, Query(rson, mid + 1, r, L, R));
    return ret;
  }
} T1, T2;
ll Solve(int A, int B) {
  memset(f, 63, sizeof(f));
  f[B] = abs(A - a[1]);
  for (int i = 1; i <= n; ++i)
    T1.a[i] = -i, T2.a[i] = i;
  T1.Build(1, 1, n);
  T2.Build(1, 1, n);
  ll inf = f[0];
  f[B] = inf;
  f[1] = abs(A - a[1]);
  for (int i = 2; i <= Q; ++i) {
    ll ret = inf;
    ret = min(ret, T1.Query(1, 1, n, 1, a[i]) + a[i]);
    ret = min(ret, T2.Query(1, 1, n, a[i], n) - a[i]);
    T1.Modify(1, 1, n, 1, n, abs(a[i] - a[i - 1]));
    T2.Modify(1, 1, n, 1, n, abs(a[i] - a[i - 1]));
    T1.Modify(1, 1, n, a[i - 1], ret - a[i - 1]);
    T2.Modify(1, 1, n, a[i - 1], ret + a[i - 1]);
    ret = min(ret, f[i - 1] + abs(a[i] - a[i - 1]));
    f[i] = ret;
  }
  return f[Q];
}
int main() {
  freopen("a.in", "r", stdin);
  n = read();
  Q = read();
  A = read();
  B = read();
  for (int i = 1; i <= Q; ++i)
    a[i] = read();
  printf("%lld\n", min(Solve(A, B), Solve(B, A)));
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define ll long long
#define MAX 200200
#define lson (now << 1)
#define rson (now << 1 | 1)
inline int read() {
  int x = 0;
  bool t = false;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-')
    ch = getchar();
  if (ch == '-')
    t = true, ch = getchar();
  while (ch <= '9' && ch >= '0')
    x = x * 10 + ch - 48, ch = getchar();
  return t ? -x : x;
}
int n, Q, A, B, a[MAX];
ll f[MAX];
struct SegMentTree {
  ll t[MAX << 2], tag[MAX << 2], a[MAX];
  void pushup(int now) { t[now] = min(t[lson], t[rson]); }
  void Build(int now, int l, int r) {
    if (l == r) {
      t[now] = f[l] + a[l];
      return;
    }
    int mid = (l + r) >> 1;
    tag[now] = 0;
    Build(lson, l, mid);
    Build(rson, mid + 1, r);
    pushup(now);
  }
  void puttag(int now, ll w) {
    t[now] += w;
    tag[now] += w;
  }
  void pushdown(int now) {
    if (!tag[now])
      return;
    puttag(lson, tag[now]);
    puttag(rson, tag[now]);
    tag[now] = 0;
  }
  void Modify(int now, int l, int r, int p, ll w) {
    if (l == r) {
      t[now] = min(t[now], w);
      return;
    }
    int mid = (l + r) >> 1;
    pushdown(now);
    if (p <= mid)
      Modify(lson, l, mid, p, w);
    else
      Modify(rson, mid + 1, r, p, w);
    pushup(now);
  }
  void Modify(int now, int l, int r, int L, int R, int w) {
    if (L <= l && r <= R) {
      puttag(now, w);
      return;
    }
    int mid = (l + r) >> 1;
    pushdown(now);
    if (L <= mid)
      Modify(lson, l, mid, L, R, w);
    if (R > mid)
      Modify(rson, mid + 1, r, L, R, w);
    pushup(now);
  }
  ll Query(int now, int l, int r, int L, int R) {
    if (L <= l && r <= R)
      return t[now];
    int mid = (l + r) >> 1;
    ll ret = 4e18;
    pushdown(now);
    if (L <= mid)
      ret = min(ret, Query(lson, l, mid, L, R));
    if (R > mid)
      ret = min(ret, Query(rson, mid + 1, r, L, R));
    return ret;
  }
} T1, T2;
ll Solve(int A, int B) {
  memset(f, 63, sizeof(f));
  f[B] = abs(A - a[1]);
  for (int i = 1; i <= n; ++i)
    T1.a[i] = -i, T2.a[i] = i;
  T1.Build(1, 1, n);
  T2.Build(1, 1, n);
  ll inf = f[0];
  f[B] = inf;
  f[1] = abs(A - a[1]);
  for (int i = 2; i <= Q; ++i) {
    ll ret = inf;
    ret = min(ret, T1.Query(1, 1, n, 1, a[i]) + a[i]);
    ret = min(ret, T2.Query(1, 1, n, a[i], n) - a[i]);
    T1.Modify(1, 1, n, 1, n, abs(a[i] - a[i - 1]));
    T2.Modify(1, 1, n, 1, n, abs(a[i] - a[i - 1]));
    T1.Modify(1, 1, n, a[i - 1], ret - a[i - 1]);
    T2.Modify(1, 1, n, a[i - 1], ret + a[i - 1]);
    ret = min(ret, f[i - 1] + abs(a[i] - a[i - 1]));
    f[i] = ret;
  }
  return f[Q];
}
int main() {
  n = read();
  Q = read();
  A = read();
  B = read();
  for (int i = 1; i <= Q; ++i)
    a[i] = read();
  printf("%lld\n", min(Solve(A, B), Solve(B, A)));
  return 0;
}