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

#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

template <class T> ostream &operator<<(ostream &os, const V<T> &v) {
  os << "[";
  for (auto p : v)
    os << p << ", ";
  os << "]";
  return os;
}

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;

int sgn(D a) { return (abs(a) <= EPS) ? 0 : (a < 0 ? -1 : 1); }
int sgn(D a, D b) { return sgn(a - b); }
// relative sign
//  int rsgn(D a, D f) {
//      if (abs(a) <= f*EPS) return 0;
//      return (a < 0) ? -1 : 1;
//  }
struct Pt2 {
  D x, y;
  Pt2() {}
  Pt2(D _x, D _y) : x(_x), y(_y) {}
  Pt2 operator+(const Pt2 &r) const { return Pt2(x + r.x, y + r.y); }
  Pt2 operator-(const Pt2 &r) const { return Pt2(x - r.x, y - r.y); }
  Pt2 operator*(const Pt2 &r) const {
    return Pt2(x * r.x - y * r.y, x * r.y + y * r.x);
  }

  Pt2 operator*(const D &r) const { return Pt2(x * r, y * r); }
  Pt2 operator/(const D &r) const { return Pt2(x / r, y / r); }

  Pt2 &operator+=(const Pt2 &r) { return *this = *this + r; }
  Pt2 &operator-=(const Pt2 &r) { return *this = *this - r; }
  Pt2 &operator*=(const Pt2 &r) { return *this = *this * r; }
  Pt2 &operator*=(const D &r) { return *this = *this * r; }
  Pt2 &operator/=(const D &r) { return *this = *this / r; }

  Pt2 operator-() const { return Pt2(-x, -y); }

  bool operator<(const Pt2 &r) const {
    return 2 * sgn(x, r.x) + sgn(y, r.y) < 0;
  }
  bool operator==(const Pt2 &r) const { return sgn((*this - r).rabs()) == 0; }

  D norm() const { return x * x + y * y; }
  D abs() const { return sqrt(norm()); }
  D rabs() const { return max(std::abs(x), std::abs(y)); } // robust abs
  D arg() const { return atan2(y, x); }

  pair<D, D> to_pair() const { return make_pair(x, y); }
  static Pt2 polar(D le, D th) { return Pt2(le * cos(th), le * sin(th)); }
};
ostream &operator<<(ostream &os, const Pt2 &p) {
  return os << "P(" << p.x << ", " << p.y << ")";
}
using P = Pt2;

struct L {
  P s, t;
  L() {}
  L(P _s, P _t) : s(_s), t(_t) {}
  P vec() const { return t - s; }
  D abs() const { return vec().abs(); }
  D arg() const { return vec().arg(); }
};
ostream &operator<<(ostream &os, const L &l) {
  return os << "L(" << l.s << ", " << l.t << ")";
}

D cross(P a, P b) { return a.x * b.y - a.y * b.x; }
D dot(P a, P b) { return a.x * b.x + a.y * b.y; }
// cross(a, b) is too small?
int sgncrs(P a, P b) {
  D cr = cross(a, b);
  if (abs(cr) <= (a.rabs() + b.rabs()) * EPS)
    return 0;
  return (cr < 0) ? -1 : 1;
}

// -2, -1, 0, 1, 2 : front, clock, on, cclock, back
int ccw(P b, P c) {
  int s = sgncrs(b, c);
  if (s)
    return s;
  if (!sgn(c.rabs()) || !sgn((c - b).rabs()))
    return 0;
  if (dot(b, c) < 0)
    return 2;
  if (dot(-b, c - b) < 0)
    return -2;
  return 0;
}
int ccw(P a, P b, P c) { return ccw(b - a, c - a); }
int ccw(L l, P p) { return ccw(l.s, l.t, p); }

using Pol = V<P>;

D area2(const Pol &pol) {
  D u = 0;
  if (!pol.size())
    return u;
  P a = pol.back();
  for (auto b : pol)
    u += cross(a, b), a = b;
  return u;
}

// 0: outside, 1: on line, 2: inside
int contains(const Pol &pol, P p) {
  if (!pol.size())
    return 0;
  int in = -1;
  P _a, _b = pol.back();
  for (int i = 0; i < int(pol.size()); i++) {
    _a = _b;
    _b = pol[i];
    P a = _a, b = _b;
    if (ccw(a, b, p) == 0)
      return 1;
    if (a.y > b.y)
      swap(a, b);
    if (!(a.y <= p.y && p.y < b.y))
      continue;
    if (sgn(a.y, p.y) ? (cross(a - p, b - p) > 0) : (a.x > p.x))
      in *= -1;
  }
  return in + 1;
}

// p must be sorted and uniqued!
Pol convex_down(const V<P> &ps) {
  assert(ps.size() >= 2);
  Pol dw;
  for (P d : ps) {
    size_t n;
    while ((n = dw.size()) > 1) {
      if (ccw(dw[n - 2], dw[n - 1], d) != -1)
        break; // line上も取る
               //            if (ccw(dw[n-2], dw[n-1], d) == 1) break;
      dw.pop_back();
    }
    dw.push_back(d);
  }
  return dw;
}

Pol convex(Pol ps) {
  sort(begin(ps), end(ps));
  ps.erase(unique(begin(ps), end(ps)), end(ps));
  if (ps.size() <= 1)
    return ps;
  Pol dw = convex_down(ps);
  reverse(begin(ps), end(ps));
  Pol up = convex_down(ps);
  dw.insert(begin(dw), begin(up) + 1, end(up) - 1);
  return dw;
}

int crossLL(const L &l, const L &m, P &r) {
  D cr1 = cross(l.vec(), m.vec()), cr2 = cross(l.vec(), l.t - m.s);
  if (sgncrs(l.vec(), m.vec()) == 0) {
    r = l.s;
    if (sgncrs(l.vec(), l.t - m.s))
      return 0;
    return -1;
  }
  r = m.s + m.vec() * (cr2 / cr1);
  return 1;
}

// スパゲッティソースをパクった、直線の左側の多角形を返却する
Pol convex_cut(const Pol &po, const L &l) {
  if (!po.size())
    return Pol{};
  int n = int(po.size());
  Pol q;
  P a, b = po.back();
  for (int i = 0; i < n; i++) {
    a = b;
    b = po[i];
    if ((ccw(l, a) % 2) * (ccw(l, b) % 2) < 0) {
      P buf;
      crossLL(l, L(a, b), buf);
      q.push_back(buf);
    }
    if (ccw(l, b) != -1)
      q.push_back(b);
  }
  return q;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(20) << fixed;

  int n;
  cin >> n;
  V<P> p(n);
  for (int i = 0; i < n; i++) {
    D x, y;
    cin >> x >> y;
    p[i] = P(x, y);
  }
  int q;
  cin >> q;
  for (int ph = 0; ph < q; ph++) {
    L l;
    D x, y;
    cin >> x >> y;
    l.s = P(x, y);
    cin >> x >> y;
    l.t = P(x, y);
    cout << area2(convex_cut(p, l)) / 2 << endl;
  }

  return 0;
}


Error: WA

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

template <class T> ostream &operator<<(ostream &os, const V<T> &v) {
  os << "[";
  for (auto p : v)
    os << p << ", ";
  os << "]";
  return os;
}

using D = double;
const D PI = acos(D(-1)), EPS = 1e-10;

int sgn(D a) { return (abs(a) <= EPS) ? 0 : (a < 0 ? -1 : 1); }
int sgn(D a, D b) { return sgn(a - b); }
// relative sign
//  int rsgn(D a, D f) {
//      if (abs(a) <= f*EPS) return 0;
//      return (a < 0) ? -1 : 1;
//  }
struct Pt2 {
  D x, y;
  Pt2() {}
  Pt2(D _x, D _y) : x(_x), y(_y) {}
  Pt2 operator+(const Pt2 &r) const { return Pt2(x + r.x, y + r.y); }
  Pt2 operator-(const Pt2 &r) const { return Pt2(x - r.x, y - r.y); }
  Pt2 operator*(const Pt2 &r) const {
    return Pt2(x * r.x - y * r.y, x * r.y + y * r.x);
  }

  Pt2 operator*(const D &r) const { return Pt2(x * r, y * r); }
  Pt2 operator/(const D &r) const { return Pt2(x / r, y / r); }

  Pt2 &operator+=(const Pt2 &r) { return *this = *this + r; }
  Pt2 &operator-=(const Pt2 &r) { return *this = *this - r; }
  Pt2 &operator*=(const Pt2 &r) { return *this = *this * r; }
  Pt2 &operator*=(const D &r) { return *this = *this * r; }
  Pt2 &operator/=(const D &r) { return *this = *this / r; }

  Pt2 operator-() const { return Pt2(-x, -y); }

  bool operator<(const Pt2 &r) const {
    return 2 * sgn(x, r.x) + sgn(y, r.y) < 0;
  }
  bool operator==(const Pt2 &r) const { return sgn((*this - r).rabs()) == 0; }

  D norm() const { return x * x + y * y; }
  D abs() const { return sqrt(norm()); }
  D rabs() const { return max(std::abs(x), std::abs(y)); } // robust abs
  D arg() const { return atan2(y, x); }

  pair<D, D> to_pair() const { return make_pair(x, y); }
  static Pt2 polar(D le, D th) { return Pt2(le * cos(th), le * sin(th)); }
};
ostream &operator<<(ostream &os, const Pt2 &p) {
  return os << "P(" << p.x << ", " << p.y << ")";
}
using P = Pt2;

struct L {
  P s, t;
  L() {}
  L(P _s, P _t) : s(_s), t(_t) {}
  P vec() const { return t - s; }
  D abs() const { return vec().abs(); }
  D arg() const { return vec().arg(); }
};
ostream &operator<<(ostream &os, const L &l) {
  return os << "L(" << l.s << ", " << l.t << ")";
}

D cross(P a, P b) { return a.x * b.y - a.y * b.x; }
D dot(P a, P b) { return a.x * b.x + a.y * b.y; }
// cross(a, b) is too small?
int sgncrs(P a, P b) {
  D cr = cross(a, b);
  if (abs(cr) <= (a.rabs() + b.rabs()) * EPS)
    return 0;
  return (cr < 0) ? -1 : 1;
}

// -2, -1, 0, 1, 2 : front, clock, on, cclock, back
int ccw(P b, P c) {
  int s = sgncrs(b, c);
  if (s)
    return s;
  if (!sgn(c.rabs()) || !sgn((c - b).rabs()))
    return 0;
  if (dot(b, c) < 0)
    return 2;
  if (dot(-b, c - b) < 0)
    return -2;
  return 0;
}
int ccw(P a, P b, P c) { return ccw(b - a, c - a); }
int ccw(L l, P p) { return ccw(l.s, l.t, p); }

using Pol = V<P>;

D area2(const Pol &pol) {
  D u = 0;
  P a = pol.back();
  for (auto b : pol)
    u += cross(a, b), a = b;
  return u;
}

// 0: outside, 1: on line, 2: inside
int contains(const Pol &pol, P p) {
  int in = -1;
  P _a, _b = pol.back();
  for (int i = 0; i < int(pol.size()); i++) {
    _a = _b;
    _b = pol[i];
    P a = _a, b = _b;
    if (ccw(a, b, p) == 0)
      return 1;
    if (a.y > b.y)
      swap(a, b);
    if (!(a.y <= p.y && p.y < b.y))
      continue;
    if (sgn(a.y, p.y) ? (cross(a - p, b - p) > 0) : (a.x > p.x))
      in *= -1;
  }
  return in + 1;
}

// p must be sorted and uniqued!
Pol convex_down(const V<P> &ps) {
  assert(ps.size() >= 2);
  Pol dw;
  for (P d : ps) {
    size_t n;
    while ((n = dw.size()) > 1) {
      if (ccw(dw[n - 2], dw[n - 1], d) != -1)
        break; // line上も取る
               //            if (ccw(dw[n-2], dw[n-1], d) == 1) break;
      dw.pop_back();
    }
    dw.push_back(d);
  }
  return dw;
}

Pol convex(Pol ps) {
  sort(begin(ps), end(ps));
  ps.erase(unique(begin(ps), end(ps)), end(ps));
  if (ps.size() <= 1)
    return ps;
  Pol dw = convex_down(ps);
  reverse(begin(ps), end(ps));
  Pol up = convex_down(ps);
  dw.insert(begin(dw), begin(up) + 1, end(up) - 1);
  return dw;
}

int crossLL(const L &l, const L &m, P &r) {
  D cr1 = cross(l.vec(), m.vec()), cr2 = cross(l.vec(), l.t - m.s);
  if (sgncrs(l.vec(), m.vec()) == 0) {
    r = l.s;
    if (sgncrs(l.vec(), l.t - m.s))
      return 0;
    return -1;
  }
  r = m.s + m.vec() * (cr2 / cr1);
  return 1;
}

// スパゲッティソースをパクった、直線の左側の多角形を返却する
Pol convex_cut(const Pol &po, const L &l) {
  Pol q;
  P a, b = po.back();
  for (int i = 0; i < int(po.size()); i++) {
    a = b;
    b = po[i];
    if ((ccw(l, a) % 2) * (ccw(l, b) % 2) < 0) {
      P buf;
      crossLL(l, L(a, b), buf);
      q.push_back(buf);
    }
    if (ccw(l, b) != -1)
      q.push_back(b);
  }
  return q;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(20) << fixed;

  int n;
  cin >> n;
  V<P> p(n);
  for (int i = 0; i < n; i++) {
    D x, y;
    cin >> x >> y;
    p[i] = P(x, y);
  }
  int q;
  cin >> q;
  for (int ph = 0; ph < q; ph++) {
    L l;
    D x, y;
    cin >> x >> y;
    l.s = P(x, y);
    cin >> x >> y;
    l.t = P(x, y);
    cout << area2(convex_cut(p, l)) / 2 << endl;
  }

  return 0;
}