double bisect(const poly &p, double lower, double upper) { if (upper - lower < 1e-5) return lower; double mid = (lower + upper) / 2; if (sgn(p.eval(mid)) == sgn(p.eval(lower))) { return bisect(p, mid, upper); } else { return bisect(p, lower, mid); } }
VD roots(const poly &p) { if (p.is_constant()) return VD(0); VD critical_values = roots(p.derivative()); critical_values.push_back(1e6); VD ans; double lower = -1e6; for (int i = 0; i < critical_values.size(); i++) { double upper = critical_values[i]; if (sgn(p.eval(lower)) != sgn(p.eval(upper))) ans.push_back(bisect(p, lower, upper)); lower = upper; } return ans; }