Problem p03851 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

typedef long long LL;

using std::swap;

const int N = 1e5 + 10;
const LL Inf = 1e18;

struct Node {
  LL x, y;
  Node(LL x = 0ll, LL y = 0ll) : x(x), y(y) {}
  Node operator-(const Node &A) const { return Node(x - A.x, y - A.y); }
} que[N];

int n, t[N];
LL f[N], l[N], r[N], sum[N];

void Init() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &t[i]);
}

LL Cross(const Node &A, const Node &B) { return A.x * B.y - A.y * B.x; }

bool better(const Node &p1, const Node &p2, int v) {
  return p1.y - v * p1.x > p2.y - v * p2.x;
}

bool better(const Node &A, const Node &B, const Node &C) {
  return Cross(B - A, C - A) >= 0;
}

void prepare(LL *f, int *t) {
  sum[0] = 0ll;
  for (int i = 1; i <= n; ++i)
    sum[i] = sum[i - 1] + t[i];
  int head = 1, tail = 0;
  que[++tail] = Node(0, 0);
  for (int i = 1; i <= n; ++i) {
    while (tail > head && better(que[tail - 1], que[tail], i))
      --tail;
    f[i] = std::max(
        (que[tail].y + 1ll * i * i - 2ll * sum[i] + i - que[tail].x * i) / 2,
        f[i - 1]);
    Node p(2ll * i, 2 * f[i] + 1ll * i * i - i + 2ll * sum[i]);
    while (tail > head && better(que[tail - 1], que[tail], p))
      tail--;
    que[++tail] = p;
  }
}

LL put[N];
void Divide(int l, int r, LL *lv, LL *rv) {
  if (l == r) {
    f[l] = std::max(f[l], lv[l - 1] + rv[l + 1] - t[l] + 1);
    return;
  }
  int mid = (l + r) >> 1;
  int head = 1, tail = 0;
  for (int i = l - 1; i < mid; ++i) {
    Node p(2ll * i, 2 * lv[i] + 1ll * i * i - i + 2ll * sum[i]);
    while (tail > head && better(que[tail - 1], que[tail], p))
      tail--;
    que[++tail] = p;
  }
  for (int i = mid; i <= r; ++i) {
    while (tail > head && better(que[tail - 1], que[tail], i))
      --tail;
    put[i] =
        (que[tail].y + 1ll * i * i - 2ll * sum[i] + i - que[tail].x * i) / 2 +
        rv[i + 1];
  }
  f[r] = std::max(put[r], f[r]);
  for (int i = r - 1; i >= mid; --i)
    put[i] = std::max(put[i], put[i + 1]), f[i] = std::max(put[i], f[i]);
  Divide(l, mid, lv, rv);
  Divide(mid + 1, r, lv, rv);
}

void Solve() {
  prepare(l, t);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]);
  prepare(r, t);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]), swap(r[i], r[n - i + 1]);

  for (int i = 1; i <= n; ++i)
    f[i] = 1 - t[i];

  sum[0] = 0ll;
  for (int i = 1; i <= n; ++i)
    sum[i] = sum[i - 1] + t[i];
  Divide(1, n, l, r);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]), swap(l[i], l[n - i + 1]),
        swap(r[i], r[n - i + 1]), swap(f[i], f[n - i + 1]);
  sum[0] = 0ll;
  for (int i = 1; i <= n; ++i)
    sum[i] = sum[i - 1] + t[i];
  Divide(1, n, r, l);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]), swap(l[i], l[n - i + 1]),
        swap(r[i], r[n - i + 1]), swap(f[i], f[n - i + 1]);

  int m, p, x;
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d", &p, &x);
    printf("%lld\n", std::max(l[p - 1] + r[p + 1], f[p] + t[p] - x));
  }
}

int main() {
  Init();
  Solve();
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

typedef long long LL;

using std::swap;

const int N = 3e5 + 10;
const LL Inf = 1e18;

struct Node {
  LL x, y;
  Node(LL x = 0ll, LL y = 0ll) : x(x), y(y) {}
  Node operator-(const Node &A) const { return Node(x - A.x, y - A.y); }
} que[N];

int n, t[N];
LL f[N], l[N], r[N], sum[N];

void Init() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &t[i]);
}

LL Cross(const Node &A, const Node &B) { return A.x * B.y - A.y * B.x; }

bool better(const Node &p1, const Node &p2, int v) {
  return p1.y - v * p1.x > p2.y - v * p2.x;
}

bool better(const Node &A, const Node &B, const Node &C) {
  return Cross(B - A, C - A) >= 0;
}

void prepare(LL *f, int *t) {
  sum[0] = 0ll;
  for (int i = 1; i <= n; ++i)
    sum[i] = sum[i - 1] + t[i];
  int head = 1, tail = 0;
  que[++tail] = Node(0, 0);
  for (int i = 1; i <= n; ++i) {
    while (tail > head && better(que[tail - 1], que[tail], i))
      --tail;
    f[i] = std::max(
        (que[tail].y + 1ll * i * i - 2ll * sum[i] + i - que[tail].x * i) / 2,
        f[i - 1]);
    Node p(2ll * i, 2 * f[i] + 1ll * i * i - i + 2ll * sum[i]);
    while (tail > head && better(que[tail - 1], que[tail], p))
      tail--;
    que[++tail] = p;
  }
}

LL put[N];
void Divide(int l, int r, LL *lv, LL *rv) {
  if (l == r) {
    f[l] = std::max(f[l], lv[l - 1] + rv[l + 1] - t[l] + 1);
    return;
  }
  int mid = (l + r) >> 1;
  int head = 1, tail = 0;
  for (int i = l - 1; i < mid; ++i) {
    Node p(2ll * i, 2 * lv[i] + 1ll * i * i - i + 2ll * sum[i]);
    while (tail > head && better(que[tail - 1], que[tail], p))
      tail--;
    que[++tail] = p;
  }
  for (int i = mid; i <= r; ++i) {
    while (tail > head && better(que[tail - 1], que[tail], i))
      --tail;
    put[i] =
        (que[tail].y + 1ll * i * i - 2ll * sum[i] + i - que[tail].x * i) / 2 +
        rv[i + 1];
  }
  f[r] = std::max(put[r], f[r]);
  for (int i = r - 1; i >= mid; --i)
    put[i] = std::max(put[i], put[i + 1]), f[i] = std::max(put[i], f[i]);
  Divide(l, mid, lv, rv);
  Divide(mid + 1, r, lv, rv);
}

void Solve() {
  prepare(l, t);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]);
  prepare(r, t);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]), swap(r[i], r[n - i + 1]);

  for (int i = 1; i <= n; ++i)
    f[i] = 1 - t[i];

  sum[0] = 0ll;
  for (int i = 1; i <= n; ++i)
    sum[i] = sum[i - 1] + t[i];
  Divide(1, n, l, r);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]), swap(l[i], l[n - i + 1]),
        swap(r[i], r[n - i + 1]), swap(f[i], f[n - i + 1]);
  sum[0] = 0ll;
  for (int i = 1; i <= n; ++i)
    sum[i] = sum[i - 1] + t[i];
  Divide(1, n, r, l);
  for (int i = 1; i <= n / 2; ++i)
    swap(t[i], t[n - i + 1]), swap(l[i], l[n - i + 1]),
        swap(r[i], r[n - i + 1]), swap(f[i], f[n - i + 1]);

  int m, p, x;
  scanf("%d", &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d", &p, &x);
    printf("%lld\n", std::max(l[p - 1] + r[p + 1], f[p] + t[p] - x));
  }
}

int main() {
  Init();
  Solve();
  return 0;
}