Problem p01337 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
double a, b, c, d;
double f(double x) { return a * x * x * x + b * x * x + c * x + d; }
// 2次方程式 ax^2 + bx + c = 0の解
vector<double> quadratic(double a, double b, double c) {
  assert(a != 0);
  double D = b * b - 4 * a * c;
  if (abs(D) < EPS)
    return vector<double>(2, -b / (2.0 * a));
  if (D < 0)
    return vector<double>();

  // |b| >> |ac|の時の桁落ちを避けるために
  // x_1 = (-b-sign(b)*sqrt(D))/(2*a), x_2 = c / (a*x_1)を利用する
  vector<double> res;
  int sign = (b >= 0) ? 1 : -1;
  double x1 = (-b - sign * sqrt(D)) / (2.0 * a);
  double x2 = c / (a * x1);
  res.push_back(x1);
  res.push_back(x2);
  return res;
}
vector<double> solve() {
  if (a < 0) {
    a *= -1;
    b *= -1;
    c *= -1;
    d *= -1;
  }
  double lb = -1e3, ub = 1e3;
  REP(iter, 300) {
    double x = (ub + lb) / 2;
    if (f(x) > 0) {
      ub = x;
    } else if (f(x) < 0) {
      lb = x;
    }
  }
  double x1 = (ub + lb) / 2;
  double A = 1;
  double B = b / a + x1;
  double C = c / a + B * x1;
  vector<double> ans = quadratic(A, B, C);
  ans.push_back(x1);
  return ans;
}

int main() {
  int N;
  cin >> N;
  while (N--) {
    cin >> a >> b >> c >> d;
    vector<double> ans = solve();
    int a[2] = {};
    REP(i, ans.size()) {
      // printf("f(%lf) = %lf\\n", ans[i], f(ans[i]));
      if (ans[i] > EPS)
        a[0]++;
      if (ans[i] < -EPS)
        a[1]++;
    }
    printf("%d %d\\n", a[0], a[1]);
  }
  /*
  REP(iter, 100000){
    a = rand() % 200 - 100;
    if(a == 0) continue;
    b = rand() % 20 -10;
    c = rand() % 20 -10;
    d = rand() % 20 -10;
    vector<double> ans = solve();
    REP(i, ans.size()){
      assert(abs(f(ans[i])) < EPS);
    }
  }
  */
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cout << *i << " ";
  cout << endl;
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-9;
const int MOD = 1000000007;
double a, b, c, d;
double f(double x) { return a * x * x * x + b * x * x + c * x + d; }
double df(double x) { return 3 * a * x * x + 2 * b * x + c; }
int main() {
  int n;
  cin >> n;
  REP(time, n) {
    cin >> a >> b >> c >> d;
    double ax[3] = {};
    ax[0] = 123.6789;
    REP(i, 1000) {
      // printf("%.12lf\\n",ax[0]);
      if (abs(df(ax[0])) == 0)
        break;
      ax[0] = ax[0] - f(ax[0]) / df(ax[0]);
    }
    assert(abs(f(ax[0])) < EPS);
    double A = 1;
    double B = b + A * ax[0];
    double C = c + B * ax[0];
    double D = B * B - 4 * A * C;
    if (abs(D) < EPS)
      D = 0;
    // printf("%lf %lf %lf -> %lf\\n",A,B,C,D);
    if (D >= 0) {
      D = sqrt(D);
      ax[1] = (-B + D) / (2 * A);
      ax[2] = (-B - D) / (2 * A);
    }
    // debug(ax, ax + 3);
    pair<int, int> ans;
    REP(i, 3) {
      // cout<<ax[i]<<endl;
      if (ax[i] > EPS)
        ans.first += 1;
      if (ax[i] < -EPS)
        ans.second += 1;
    }
    printf("%d %d\\n", ans.first, ans.second);
  }
  return 0;
}