Problem p03185 (C++)

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

const int M = 1 << 20, N = 2 * M, INF = 1e18;

struct Tree {
  int a[N], b[N], d[N], f[N];

  void init() {
    for (int i = M; i < N; i++)
      f[i] = 1 + (d[i] = i - M);
    for (int i = M - 1; i > -1; i--) {
      d[i] = d[i * 2];
      f[i] = f[i * 2 + 1];
    }
    for (int i = 0; i < N; i++) {
      a[i] = 0;
      b[i] = INF;
    }
  }

  void insert(int i, int A, int B) {
    int deb[] = {d[i] * A + B, d[i] * a[i] + b[i]},
        fin[] = {f[i] * A + B, f[i] * a[i] + b[i]};
    // cout << A << ' ' << B << ' ' << d[i] << ' ' << f[i] << ' ' << deb[0] << '
    // ' << deb[1] << ' ' << fin[0] << ' ' << fin[1] << '\n';
    if (deb[0] <= deb[1] && fin[0] <= fin[1]) {
      a[i] = A;
      b[i] = B;
    } else if (!(deb[1] <= deb[0] && fin[1] <= fin[0])) {
      int m = (d[i] + f[i]) / 2, med[] = {m * A + B, m * a[i] + b[i]};
      if (med[0] < med[1]) {
        swap(A, a[i]);
        swap(B, b[i]);
        swap(deb[0], deb[1]);
      }
      if (deb[0] < deb[1])
        insert(i * 2, A, B);
      else
        insert(i * 2 + 1, A, B);
    }
  }

  int getMin(int i, int x) {
    if (i == 0)
      return INF;
    return min(getMin(i / 2, x), a[i] * x + b[i]);
  }
};

int n, c, h[M], cost[M];

signed main() {
  /*
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  */
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  Tree tree;
  tree.init();
  cin >> n >> c;
  for (int i = 0; i < n; i++)
    cin >> h[i];

  for (int i = 0, j = 1; j < n; i++, j++) {
    tree.insert(1, -(h[i] * 2), c + cost[i] + h[i] * h[i]);
    // cout << -(h[i]*2) << ' ' << c + cost[i] + h[i] * h[i] << ' ' << cost[i]
    // << '\n';
    cost[j] = tree.getMin(h[j] + M, h[j]) + h[j] * h[j];
    // cout << h[j] << ' ' << tree.getMin(h[j] + M, h[j]) << ' ' << cost[j] <<
    // '\n' << '\n';
  }
  cout << cost[n - 1] << '\n';
}

Fixed submission:
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int M = 1 << 20, N = 2 * M, INF = 1e18;

struct Tree {
  int a[N], b[N], d[N], f[N];

  void init() {
    for (int i = M; i < N; i++)
      f[i] = 1 + (d[i] = i - M);
    for (int i = M - 1; i > -1; i--) {
      d[i] = d[i * 2];
      f[i] = f[i * 2 + 1];
    }
    for (int i = 0; i < N; i++) {
      a[i] = 0;
      b[i] = INF;
    }
  }

  void insert(int i, int A, int B) {
    if (i >= N)
      return;
    int deb[] = {d[i] * A + B, d[i] * a[i] + b[i]},
        fin[] = {f[i] * A + B, f[i] * a[i] + b[i]};
    // cout << A << ' ' << B << ' ' << d[i] << ' ' << f[i] << ' ' << deb[0] << '
    // ' << deb[1] << ' ' << fin[0] << ' ' << fin[1] << '\n';
    if (deb[0] <= deb[1] && fin[0] <= fin[1]) {
      a[i] = A;
      b[i] = B;
    } else if (!(deb[1] <= deb[0] && fin[1] <= fin[0])) {
      int m = (d[i] + f[i]) / 2, med[] = {m * A + B, m * a[i] + b[i]};
      if (med[0] < med[1]) {
        swap(A, a[i]);
        swap(B, b[i]);
        swap(deb[0], deb[1]);
      }
      if (deb[0] < deb[1])
        insert(i * 2, A, B);
      else
        insert(i * 2 + 1, A, B);
    }
  }

  int getMin(int i, int x) {
    if (i == 0)
      return INF;
    return min(getMin(i / 2, x), a[i] * x + b[i]);
  }
};

int n, c, h[M], cost[M];

signed main() {
  /*
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  */
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  Tree tree;
  tree.init();
  cin >> n >> c;
  for (int i = 0; i < n; i++)
    cin >> h[i];

  for (int i = 0, j = 1; j < n; i++, j++) {
    tree.insert(1, -(h[i] * 2), c + cost[i] + h[i] * h[i]);
    // cout << -(h[i]*2) << ' ' << c + cost[i] + h[i] * h[i] << ' ' << cost[i]
    // << '\n';
    cost[j] = tree.getMin(h[j] + M, h[j]) + h[j] * h[j];
    // cout << h[j] << ' ' << tree.getMin(h[j] + M, h[j]) << ' ' << cost[j] <<
    // '\n' << '\n';
  }
  cout << cost[n - 1] << '\n';
}