QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#35601 | #972. Circle | AutumnKite | AC ✓ | 689ms | 4396kb | C++17 | 17.5kb | 2022-06-17 10:52:49 | 2022-06-17 10:52:52 |
Judging History
answer
#include <bits/stdc++.h>
template<typename Tp, typename Comp>
class geometry {
public:
static constexpr Tp pi = 3.14159265358979324L;
static int sgn(const Tp &a, const Tp &b = Tp()) {
static Comp cmp;
return cmp(a, b) ? -1 : (cmp(b, a) ? 1 : 0);
}
static Tp safe_sqrt(const Tp &a) {
if (!sgn(a)) {
return Tp();
} else {
return std::sqrt(a);
}
}
struct point {
Tp x, y;
point() : x(), y() {}
point(const Tp &t_x, const Tp &t_y) : x(t_x), y(t_y) {}
Tp len2() const {
return x * x + y * y;
}
Tp len() const {
return safe_sqrt(len2());
}
point unit2() const {
Tp l = len2();
if (!sgn(l)) {
return point();
}
return point(x / l, y / l);
}
point unit() const {
Tp l = len();
if (!sgn(l)) {
return point();
}
return point(x / l, y / l);
}
Tp angle() const {
Tp t = std::atan2(y, x);
if (sgn(t) < 0) {
t += 2 * pi;
}
return t;
}
point rotate(Tp th) const {
return point(x * std::cos(th) - y * std::sin(th),
y * std::cos(th) + x * std::sin(th));
}
point rotate90() const {
return point(-y, x);
}
point &operator+=(const point &rhs) {
x += rhs.x, y += rhs.y;
return *this;
}
point &operator-=(const point &rhs) {
x -= rhs.x, y -= rhs.y;
return *this;
}
point &operator*=(const Tp &rhs) {
x *= rhs, y *= rhs;
return *this;
}
point &operator/=(const Tp &rhs) {
x /= rhs, y /= rhs;
return *this;
}
bool sgn_equal(const point &rhs) const {
return !sgn(x, rhs.x) && !sgn(y, rhs.y);
}
friend point operator+(const point &lhs, const point &rhs) {
return point(lhs.x + rhs.x, lhs.y + rhs.y);
}
friend point operator-(const point &lhs, const point &rhs) {
return point(lhs.x - rhs.x, lhs.y - rhs.y);
}
friend point operator*(const point &lhs, const Tp &rhs) {
return point(lhs.x * rhs, lhs.y * rhs);
}
friend point operator*(const Tp &lhs, const point &rhs) {
return point(lhs * rhs.x, lhs * rhs.y);
}
friend point operator/(const point &lhs, const Tp &rhs) {
return point(lhs.x / rhs, lhs.y / rhs);
}
friend bool operator==(const point &lhs, const point &rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
friend bool operator<(const point &lhs, const point &rhs) {
return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y);
}
friend std::istream &operator>>(std::istream &in, point &p) {
return in >> p.x >> p.y;
}
friend std::ostream &operator<<(std::ostream &out, const point &p) {
return out << p.x << " " << p.y;
}
};
static Tp dot(const point &a, const point &b) {
return a.x * b.x + a.y * b.y;
}
static Tp cross(const point &a, const point &b) {
return a.x * b.y - a.y * b.x;
}
static Tp angle(const point &a, const point &b) {
Tp t = std::atan2(cross(a, b), dot(a, b));
if (sgn(t) < 0) {
t += 2 * pi;
}
return t;
}
static Tp distance2(const point &a, const point &b) {
return (a - b).len2();
}
static Tp distance(const point &a, const point &b) {
return (a - b).len();
}
enum direction_t {
COUNTER_CLOCKWISE,
CLOCKWISE,
ONLINE_BACK,
ONLINE_FRONT,
ON_SEGMENT
};
struct line {
point a, b;
line() : a(), b() {}
line(const point &t_a, const point &t_b) : a(t_a), b(t_b) {}
Tp get_Y(const Tp &X) const {
if (sgn(a.x, b.x) == 0) {
return a.y;
}
return (a + (X - a.x) / (b.x - a.x) * (b - a)).y;
}
line rev() const {
return line(b, a);
}
direction_t direction(const point &p) const {
int t = sgn(cross(b - a, p - a));
if (t > 0) {
return COUNTER_CLOCKWISE;
}
if (t < 0) {
return CLOCKWISE;
}
Tp l1 = dot(p - a, b - a);
if (sgn(l1) < 0) {
return ONLINE_BACK;
}
Tp l2 = dot(b - a, b - a);
if (sgn(l1, l2) > 0) {
return ONLINE_FRONT;
}
return ON_SEGMENT;
}
point midpoint() const {
return (a + b) / 2;
}
line vertical_bisector() const {
point p = midpoint();
return line(p, p + (b - p).rotate90());
}
};
static bool parallel(const line &a, const line &b) {
return !sgn(cross(a.b - a.a, b.b - b.a));
}
static point projection(const line &l, const point &p) {
return l.a + (l.b - l.a).unit2() * dot(p - l.a, l.b - l.a);
}
static std::vector<point> line_cross(const line &a, const line &b) {
if (parallel(a, b)) {
return {};
}
point u = a.a - b.a, v = a.b - a.a, w = b.b - b.a;
return {a.a + cross(w, u) / cross(v, w) * v};
}
static std::vector<point> segment_cross(const line &a, const line &b) {
Tp t1 = cross(b.a - a.a, a.b - a.a), t2 = cross(b.b - a.a, a.b - a.a);
Tp t3 = cross(a.a - b.a, b.b - b.a), t4 = cross(a.b - b.a, b.b - b.a);
if (!sgn(t1) && !sgn(t2) && !sgn(t3) && !sgn(t4)) {
if (sgn(std::min(a.a.x, a.b.x), std::max(b.a.x, b.b.x)) > 0) {
return {};
}
if (sgn(std::min(b.a.x, b.b.x), std::max(a.a.x, a.b.x)) > 0) {
return {};
}
if (sgn(std::min(a.a.y, a.b.y), std::max(b.a.y, b.b.y)) > 0) {
return {};
}
if (sgn(std::min(b.a.y, b.b.y), std::max(a.a.y, a.b.y)) > 0) {
return {};
}
return {std::max(std::min(a.a, a.b), std::min(b.a, b.b)),
std::min(std::max(a.a, a.b), std::max(b.a, b.b))};
}
if (sgn(t1) * sgn(t2) > 0) {
return {};
}
if (sgn(t3) * sgn(t4) > 0) {
return {};
}
return line_cross(a, b);
}
static std::vector<point> segment_set_cross(const std::vector<line> &s) {
using pointer = typename std::vector<line>::const_iterator;
std::vector<std::tuple<Tp, bool, pointer>> op;
for (pointer it = s.begin(); it != s.end(); ++it) {
if (sgn(it->a.x, it->b.x) > 0) {
op.emplace_back(it->a.x, true, it);
op.emplace_back(it->b.x, false, it);
} else {
op.emplace_back(it->a.x, false, it);
op.emplace_back(it->b.x, true, it);
}
}
std::sort(op.begin(), op.end(), [&](const auto &a, const auto &b) {
int t = sgn(std::get<0>(a), std::get<0>(b));
if (t) {
return t < 0;
}
return std::make_pair(std::get<1>(a), std::get<2>(a)) <
std::make_pair(std::get<1>(b), std::get<2>(b));
});
Tp now = 0;
std::function<bool(pointer, pointer)> cmp = [&](pointer i, pointer j) {
int t = sgn(i->get_Y(now), j->get_Y(now));
if (t) {
return t < 0;
}
return i < j;
};
std::set<pointer, decltype(cmp)> S(cmp);
bool ok = false;
point ans;
auto upd = [&](pointer i, pointer j) {
auto tmp = segment_cross(*i, *j);
if (!tmp.empty()) {
if (!ok) {
ok = true;
ans = *tmp.begin();
} else {
ans = std::min(ans, *tmp.begin());
}
}
return tmp;
};
for (auto p : op) {
now = std::get<0>(p);
if (ok && sgn(ans.x, now) < 0) {
break;
}
pointer it = std::get<2>(p);
if (std::get<1>(p)) {
S.erase(it);
auto nx = S.upper_bound(it);
if (nx != S.begin() && nx != S.end()) {
upd(*std::prev(nx), *nx);
}
} else {
auto nx = S.upper_bound(it);
if (nx != S.end()) {
upd(it, *nx);
}
if (nx != S.begin()) {
upd(*std::prev(nx), it);
}
S.insert(it);
}
}
if (ok) {
return {ans};
} else {
return {};
}
}
using polygon = std::vector<point>;
static polygon convex_hull(std::vector<point> f) {
if (f.empty()) {
return polygon();
}
std::size_t t = 0;
for (std::size_t i = 1; i < f.size(); ++i) {
if (f[i].y < f[t].y || (f[i].y == f[t].y && f[i].x < f[t].x)) {
t = i;
}
}
std::rotate(f.begin(), f.begin() + t, f.end());
std::sort(f.begin() + 1, f.end(), [&](const point &p, const point &q) {
int tmp = sgn(cross(p - f[0], q - f[0]));
if (tmp) {
return tmp > 0;
}
return distance(p, f[0]) < distance(q, f[0]);
});
polygon p;
for (std::size_t i = 0; i < f.size(); ++i) {
while (p.size() > 1 &&
cross(f[i] - p.back(), p[p.size() - 2] - p.back()) <= 0) {
p.pop_back();
}
p.push_back(f[i]);
}
return p;
}
static polygon convex_cut(const polygon &g, const line &l) {
polygon res;
for (std::size_t i = 0; i < g.size(); ++i){
point u = g[i], v = g[(i + 1) % g.size()];
if (sgn(cross(l.b - l.a, u - l.a)) >= 0) {
res.push_back(u);
if (sgn(cross(l.b - l.a, v - l.a)) < 0) {
res.push_back(line_cross(line(u, v), l)[0]);
}
} else if (sgn(cross(l.b - l.a, v - l.a)) > 0) {
res.push_back(line_cross(line(u, v), l)[0]);
}
}
return res;
}
static Tp polygon_directed_area(const polygon &g) {
Tp s = 0;
for (std::size_t i = 0; i < g.size(); ++i) {
s += cross(g[i], g[(i + 1) % g.size()]);
}
return s / 2;
}
static polygon half_plane_intersection(const std::vector<line> &ls,
const point &min, const point &max) {
std::vector<std::pair<Tp, line>> f;
for (const auto &l : ls) {
f.emplace_back(0, l);
}
f.emplace_back(0, line(point(min.x, min.y), point(max.x, min.y)));
f.emplace_back(0, line(point(max.x, min.y), point(max.x, max.y)));
f.emplace_back(0, line(point(max.x, max.y), point(min.x, max.y)));
f.emplace_back(0, line(point(min.x, max.y), point(min.x, min.y)));
for (auto &p : f) {
p.first = (p.second.b - p.second.a).angle();
}
std::sort(f.begin(), f.end(), [&](const auto &a, const auto &b) {
int t = sgn(a.first, b.first);
if (t) {
return t < 0;
}
return a.second.direction(b.second.a) == CLOCKWISE;
});
std::deque<line> Ql;
std::deque<point> Qp;
Ql.push_back(f[0].second);
for (std::size_t i = 1; i < f.size(); ++i) {
if (sgn(f[i - 1].first, f[i].first)) {
while (!Qp.empty() && f[i].second.direction(Qp.back()) == CLOCKWISE) {
Qp.pop_back();
Ql.pop_back();
}
while (!Qp.empty() && f[i].second.direction(Qp.front()) == CLOCKWISE) {
Qp.pop_front();
Ql.pop_front();
}
auto tmp = line_cross(Ql.back(), f[i].second);
if (tmp.empty()) {
return polygon();
}
Qp.push_back(tmp[0]);
Ql.push_back(f[i].second);
}
}
while (!Qp.empty() && Ql.front().direction(Qp.back())) {
Qp.pop_back();
Ql.pop_back();
}
if (Ql.size() < 3) {
return polygon();
}
auto tmp = line_cross(Ql.back(), Ql.front());
if (tmp.empty()) {
return polygon();
}
Qp.push_back(tmp[0]);
return polygon(Qp.begin(), Qp.end());
}
static std::vector<std::size_t> half_plane_intersection_id(
const std::vector<line> &ls, const point &min, const point &max) {
std::vector<std::pair<std::pair<Tp, std::size_t>, line>> f;
for (std::size_t i = 0; i < ls.size(); ++i) {
f.emplace_back(std::pair<Tp, std::size_t>(0, i), ls[i]);
}
std::pair<Tp, std::size_t> add(0, -1);
f.emplace_back(add, line(point(min.x, min.y), point(max.x, min.y)));
f.emplace_back(add, line(point(max.x, min.y), point(max.x, max.y)));
f.emplace_back(add, line(point(max.x, max.y), point(min.x, max.y)));
f.emplace_back(add, line(point(min.x, max.y), point(min.x, min.y)));
for (auto &p : f) {
p.first.first = (p.second.b - p.second.a).angle();
}
std::sort(f.begin(), f.end(), [&](const auto &a, const auto &b) {
int t = sgn(a.first.first, b.first.first);
if (t) {
return t < 0;
}
return a.second.direction(b.second.a) == CLOCKWISE;
});
std::deque<std::pair<std::size_t, line>> Ql;
std::deque<point> Qp;
Ql.emplace_back(f[0].first.second, f[0].second);
for (std::size_t i = 1; i < f.size(); ++i) {
if (sgn(f[i - 1].first.first, f[i].first.first)) {
while (!Qp.empty() && f[i].second.direction(Qp.back()) == CLOCKWISE) {
Qp.pop_back();
Ql.pop_back();
}
while (!Qp.empty() && f[i].second.direction(Qp.front()) == CLOCKWISE) {
Qp.pop_front();
Ql.pop_front();
}
auto tmp = line_cross(Ql.back().second, f[i].second);
if (tmp.empty()) {
return std::vector<std::size_t>();
}
Qp.push_back(tmp[0]);
Ql.emplace_back(f[i].first.second, f[i].second);
}
}
while (!Qp.empty() && Ql.front().second.direction(Qp.back())) {
Qp.pop_back();
Ql.pop_back();
}
if (Ql.size() < 3) {
return std::vector<std::size_t>();
}
auto tmp = line_cross(Ql.back().second, Ql.front().second);
if (tmp.empty()) {
return std::vector<std::size_t>();
}
Qp.push_back(tmp[0]);
std::vector<std::size_t> res;
for (const auto &p : Ql) {
if (p.first != add.second) {
res.push_back(p.first);
}
}
return res;
}
struct circle {
point o;
Tp r;
circle() : o(), r() {}
circle(const point &t_o, const Tp &t_r) : o(t_o), r(t_r) {}
};
static int circle_point_relation(const circle &a, const point &p) {
return sgn(distance2(a.o, p), a.r * a.r);
}
static std::vector<point> circle_cross(const circle &a, const circle &b) {
Tp d = distance(a.o, b.o);
if (sgn(d, a.r + b.r) > 0 || sgn(d, std::abs(a.r - b.r)) < 0 || !sgn(d)) {
return {};
}
Tp x = (a.r * a.r - b.r * b.r + d * d) / (d * 2);
Tp h = safe_sqrt(a.r * a.r - x * x);
point p = a.o + x * (b.o - a.o).unit();
point v = h * (b.o - a.o).unit().rotate90();
if (!sgn(v.x) && !sgn(v.y)) {
return {p};
} else {
return {p - v, p + v};
}
}
static std::vector<point> circle_tangent(const circle &a, const point &p) {
Tp d = distance(a.o, p);
int t = sgn(d, a.r);
if (t < 0) {
return {};
} else if (t == 0) {
return {p};
} else {
return circle_cross(circle(p, safe_sqrt(d * d - a.r * a.r)), a);
}
}
static std::vector<point> circle_common_tangent_out(const circle &a,
const circle &b) {
if (!sgn(a.r, b.r)) {
point p = (a.o - b.o).unit().rotate90() * a.r;
return {a.o - p, a.o + p};
}
point p = (a.o * b.r - b.o * a.r) / (b.r - a.r);
return circle_tangent(a, p);
}
static std::vector<point> circle_line_cross(const circle &c, const line &l) {
point p = projection(line(l.a, l.b), c.o), v = (l.b - l.a).unit();
Tp d = distance(p, c.o);
if (sgn(d, c.r) > 0) {
return {};
}
Tp t = sqrt(c.r * c.r - (p - c.o).len2());
if (!sgn(t)) {
return {p};
} else {
return {p - v * t, p + v * t};
}
}
};
struct double_compare {
constexpr bool operator()(const double &a, const double &b) const {
return a + 1e-9 <= b;
}
};
using geo = geometry<double, double_compare>;
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.setf(std::ios::fixed);
std::cout.precision(3);
int T;
std::cin >> T;
for (int test = 1; test <= T; ++test) {
geo::point A, B;
geo::circle C;
std::cin >> A >> B >> C.o >> C.r;
// if (test == 634) {
// std::cout << A.x << "," << A.y << "," << B.x << "," << B.y << "," << C.o.x << "," << C.o.y << "," << C.r << "\n";
// }
auto pA = geo::circle_tangent(C, A);
auto pB = geo::circle_tangent(C, B);
if (pA.size() == 1) {
pA.push_back(pA[0]);
}
if (pB.size() == 1) {
pB.push_back(pB[0]);
}
auto tmp = geo::circle_line_cross(C, geo::line(A, B));
if (!tmp.empty() &&
geo::line(A, B).direction(tmp[0]) == geo::ON_SEGMENT &&
geo::sgn(geo::distance(B, tmp[0])) > 0) {
double s0 = geo::distance(A, pA[0]) + geo::distance(B, pB[1]) +
geo::angle(pA[0] - C.o, pB[1] - C.o) * C.r;
double s1 = geo::distance(B, pB[0]) + geo::distance(A, pA[1]) +
geo::angle(pB[0] - C.o, pA[1] - C.o) * C.r;
std::cout << std::min(s0, s1) << "\n";
continue;
}
double l, r;
if (geo::sgn(geo::cross(pA[1] - C.o, pB[1] - C.o)) > 0) {
l = (pB[1] - C.o).angle();
} else {
l = (pA[1] - C.o).angle();
}
if (geo::sgn(geo::cross(pA[0] - C.o, pB[0] - C.o)) > 0) {
r = (pA[0] - C.o).angle();
} else {
r = (pB[0] - C.o).angle();
}
if (geo::sgn(r, l) < 0) {
r += 2 * geo::pi;
}
auto calc = [&](double x) {
auto P = C.o + geo::point(C.r, 0).rotate(x);
return geo::distance(A, P) + geo::distance(B, P);
};
for (int i = 0; i < 60; ++i) {
double mid = (l + r) / 2;
if (calc(mid) > calc(mid + 1e-6)) {
l = mid;
} else {
r = mid;
}
}
std::cout << calc(l) << "\n";
}
}
/*
1
-8 8 2 8 10 2 10
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 4124kb
input:
3 0 0 2 2 1 1 1 0 0 2 2 1 0 1 0 0 2 2 1 -1 1
output:
3.571 2.927 3.116
result:
ok 3 tokens
Test #2:
score: 0
Accepted
time: 674ms
memory: 4396kb
input:
100000 -9 -2 10 -3 -5 1 1 -7 0 -5 5 4 -8 10 6 -7 -2 -4 0 10 1 -5 -4 9 3 2 -10 9 10 3 1 -10 -10 -5 7 0 4 4 -1 2 6 2 -8 -10 4 -2 -1 4 3 2 8 4 10 -4 -9 4 8 0 -4 -10 8 -2 1 8 -4 -2 9 2 -3 3 -10 6 -4 1 6 2 8 -6 -7 -10 -4 1 -6 7 4 9 -1 9 -1 4 5 0 -7 4 1 10 -3 7 5 4 1 6 8 -6 1 7 8 -3 -9 -7 -1 5 -5 -2 -8 9 ...
output:
19.764 10.267 30.231 15.704 21.568 7.086 18.779 30.648 15.732 16.598 11.180 5.102 5.000 8.957 22.348 20.509 11.755 12.130 25.936 18.512 26.847 17.582 22.441 19.312 27.234 23.249 17.102 17.045 21.845 20.463 11.735 5.657 17.511 28.328 11.520 10.298 14.765 26.516 23.500 23.901 29.973 23.523 15.324 31.3...
result:
ok 100000 tokens
Test #3:
score: 0
Accepted
time: 669ms
memory: 4280kb
input:
100000 -2 5 -6 -9 3 -4 7 -2 -8 -10 0 7 -8 4 -7 -3 -6 0 -2 10 5 10 0 3 -1 7 -9 3 1 7 -2 -6 2 3 1 8 6 8 9 -9 -5 1 0 3 7 6 6 -5 9 3 1 -4 3 9 2 6 -6 -4 -3 10 9 -5 10 7 6 10 1 10 -6 7 -7 -1 6 -9 1 -6 1 4 3 -5 2 0 8 6 4 -7 -7 3 -3 9 5 0 -1 4 -8 -9 -7 1 -9 8 1 -4 10 3 1 8 -9 1 5 4 6 3 -10 -9 9 -2 7 2 3 -3 ...
output:
14.571 20.073 14.699 13.091 13.483 40.275 7.763 7.430 17.920 5.831 15.386 9.144 16.861 21.974 29.270 15.667 21.024 14.336 19.970 20.850 35.180 15.158 5.000 8.844 13.799 27.803 17.549 15.395 30.598 15.420 18.148 11.447 16.646 22.192 9.062 18.266 22.636 12.331 18.850 13.002 17.786 9.280 14.138 18.164 ...
result:
ok 100000 tokens
Test #4:
score: 0
Accepted
time: 664ms
memory: 4300kb
input:
100000 -2 2 -4 7 -3 -5 2 -8 -6 -3 8 0 0 3 3 7 8 2 9 -8 3 10 7 3 -5 10 -4 1 6 1 -9 7 10 -10 2 -7 -2 6 -1 -6 6 3 6 7 -6 -9 9 -4 8 -2 4 -6 2 -9 -8 2 -3 -2 0 5 4 -4 4 7 3 0 -9 -8 -8 6 2 2 0 -3 -9 -8 4 2 7 4 2 -9 2 1 -5 10 -5 4 9 5 5 -8 6 -3 -6 -7 -2 3 -5 -3 6 -1 -10 7 8 10 -6 -10 6 10 10 3 -10 9 4 -8 -5...
output:
15.145 15.704 20.283 16.832 33.337 17.299 20.109 20.366 10.468 16.358 17.241 23.132 19.226 13.117 14.891 31.987 22.165 17.290 15.675 36.938 19.550 15.103 21.134 12.175 25.859 18.339 14.831 13.684 12.791 13.091 5.657 16.585 19.661 27.292 26.161 13.570 9.697 16.106 17.800 21.011 21.113 8.490 24.768 30...
result:
ok 100000 tokens
Test #5:
score: 0
Accepted
time: 685ms
memory: 4352kb
input:
100000 -888 252 735 -600 354 917 115 823 -392 -224 23 -927 133 559 -480 648 545 -735 -221 780 1 -929 933 -27 457 165 435 169 96 215 -788 757 -995 -218 667 -315 -925 582 -980 329 -162 315 495 322 -979 673 -467 -781 589 -261 161 718 330 -890 -766 778 599 -261 -618 -181 -79 -198 429 -892 729 -949 672 5...
output:
2795.207 1426.301 1986.922 1065.587 1179.904 1336.880 2074.228 1569.596 1516.343 2047.076 2037.565 1278.256 1366.915 704.215 1637.810 823.846 1687.226 1411.903 1985.605 2226.704 2408.212 419.518 3168.560 1582.364 734.685 1266.701 2931.680 1921.424 567.081 1639.716 2808.834 2541.282 1182.642 2148.445...
result:
ok 100000 tokens
Test #6:
score: 0
Accepted
time: 689ms
memory: 4340kb
input:
100000 311 -823 238 -177 14 942 414 458 -867 611 877 -596 500 434 -102 -509 873 -974 424 -322 537 -331 -543 676 -247 815 646 687 -53 -52 -381 -433 999 -569 715 66 51 -888 579 650 475 301 670 568 -432 34 -571 550 395 0 -423 466 -396 -932 412 35 -98 665 791 -320 670 755 710 200 -926 -644 211 920 -434 ...
output:
2103.154 2333.474 1126.332 1326.118 1180.103 1712.197 1280.231 2796.425 1338.385 1733.371 1397.161 2224.141 2997.568 2301.324 2463.509 2143.719 1424.038 1232.972 2319.448 571.006 2821.620 1578.404 1296.411 1517.902 728.982 2163.288 2420.932 1793.361 1321.645 2143.605 3151.535 1031.383 1820.310 1638....
result:
ok 100000 tokens