Problem p03185 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define mod 1000000007
#define FOR(x, to) for (int x = 0; x < (to); x++)
#define FORR(x, arr) for (auto &x : arr)
#define ALL(a) (a.begin()), (a.end())
#define ZERO(a) memset(a, 0, sizeof(a))
#define MINUS(a) memset(a, 0xff, sizeof(a))
#define long long long
inline int rei() {
  int x;
  cin >> x;
  return x;
}
inline long rel() {
  long x;
  cin >> x;
  return x;
}
inline string res() {
  string x;
  cin >> x;
  return x;
}
//-------------------------------------------------------
struct ConvexHullTrick {
  pair<long, long> Point[20100];
  int p;
  ConvexHullTrick() : p(0) {}
  // aは単調増加でないといけない
  void Add(long a, long b) {
    while (p >= 2 && !Need(Point[p - 2], Point[p - 1], {a, b})) {
      p--;
    }
    Point[p] = {a, b};
    p++;
  }
  // 1つはAddしていないといけない
  long Query(long x) { return Calc(x, findMax(x)); }
  // 最初のクエリの前にpを減らす必要がある
  void Start() { p--; }
  // 2分探索で探索
  int findMax(long x) {
    int bf = 0;
    int bl = p - 1;
    while (bf != bl) {
      int bc = (bf + bl) / 2;
      if (bc == p || Calc(x, bc) >= Calc(x, bc + 1)) {
        bl = bc;
      } else {
        bf = bc + 1;
      }
    }
    return bf;
  }
  long Calc(long x, int i) { return Point[i].first * x + Point[i].second; }
  // p1,p2,p3があるときp2は必要か
  bool Need(pair<long, long> p1, pair<long, long> p2, pair<long, long> p3) {
    return (p2.first - p1.first) * (p2.second - p3.second) >
           (p3.first - p2.first) * (p1.second - p2.second);
  }
  void Free() { p = 0; }
};
long H[200000];
void Calc() {
  int N = rei();
  long C = rel();
  for (int i = 0; i < N; i++) {
    H[i] = rei();
  }
  ConvexHullTrick CHT;
  CHT.Add(2 * H[0], -H[0] * H[0] - C);
  for (int i = 1; i < N - 1; i++) {
    long t = H[i] * H[i] - CHT.Query(H[i]);
    CHT.Add(2 * H[i], -t - C - H[i] * H[i]);
  }
  long ans = H[N - 1] * H[N - 1] - CHT.Query(H[N - 1]);
  cout << ans << endl;
}
int main(int argc, char **argv) {
  ios::sync_with_stdio(false), cin.tie(0);
  cout.tie(0);
  Calc();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define mod 1000000007
#define FOR(x, to) for (int x = 0; x < (to); x++)
#define FORR(x, arr) for (auto &x : arr)
#define ALL(a) (a.begin()), (a.end())
#define ZERO(a) memset(a, 0, sizeof(a))
#define MINUS(a) memset(a, 0xff, sizeof(a))
#define long long long
inline int rei() {
  int x;
  cin >> x;
  return x;
}
inline long rel() {
  long x;
  cin >> x;
  return x;
}
inline string res() {
  string x;
  cin >> x;
  return x;
}
//-------------------------------------------------------
struct ConvexHullTrick {
  pair<long, long> Point[201000];
  int p;
  ConvexHullTrick() : p(0) {}
  // aは単調増加でないといけない
  void Add(long a, long b) {
    while (p >= 2 && !Need(Point[p - 2], Point[p - 1], {a, b})) {
      p--;
    }
    Point[p] = {a, b};
    p++;
  }
  // 1つはAddしていないといけない
  long Query(long x) { return Calc(x, findMax(x)); }
  // 最初のクエリの前にpを減らす必要がある
  void Start() { p--; }
  // 2分探索で探索
  int findMax(long x) {
    int bf = 0;
    int bl = p - 1;
    while (bf != bl) {
      int bc = (bf + bl) / 2;
      if (bc == p || Calc(x, bc) >= Calc(x, bc + 1)) {
        bl = bc;
      } else {
        bf = bc + 1;
      }
    }
    return bf;
  }
  long Calc(long x, int i) { return Point[i].first * x + Point[i].second; }
  // p1,p2,p3があるときp2は必要か
  bool Need(pair<long, long> p1, pair<long, long> p2, pair<long, long> p3) {
    return (p2.first - p1.first) * (p2.second - p3.second) >
           (p3.first - p2.first) * (p1.second - p2.second);
  }
  void Free() { p = 0; }
};
long H[200000];
void Calc() {
  int N = rei();
  long C = rel();
  for (int i = 0; i < N; i++) {
    H[i] = rei();
  }
  ConvexHullTrick CHT;
  CHT.Add(2 * H[0], -H[0] * H[0] - C);
  for (int i = 1; i < N - 1; i++) {
    long t = H[i] * H[i] - CHT.Query(H[i]);
    CHT.Add(2 * H[i], -t - C - H[i] * H[i]);
  }
  long ans = H[N - 1] * H[N - 1] - CHT.Query(H[N - 1]);
  cout << ans << endl;
}
int main(int argc, char **argv) {
  ios::sync_with_stdio(false), cin.tie(0);
  cout.tie(0);
  Calc();
  return 0;
}