QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#607595#9434. Italian Cuisineucup-team4435#AC ✓19ms4800kbC++2027.2kb2024-10-03 15:29:172024-10-03 15:29:18

Judging History

你现在查看的是最新测评结果

  • [2024-10-03 15:29:18]
  • 评测
  • 测评结果:AC
  • 用时:19ms
  • 内存:4800kb
  • [2024-10-03 15:29:17]
  • 提交

answer

#include "bits/stdc++.h"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;

using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;

int Bit(int mask, int b) { return (mask >> b) & 1; }

template<class T>
bool ckmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool ckmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return true;
    }
    return false;
}

// [l, r)
template<typename T, typename F>
T FindFirstTrue(T l, T r, const F &predicat) {
    --l;
    while (r - l > 1) {
        T mid = l + (r - l) / 2;
        if (predicat(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    return r;
}


template<typename T, typename F>
T FindLastFalse(T l, T r, const F &predicat) {
    return FindFirstTrue(l, r, predicat) - 1;
}

const int INFi = 1e9;
const ll INF = 2e18;
const int LG = 20;


bool Equal(ll A, ll B) {
    return A == B;
}

bool Less(ll A, ll B) {
    return A < B;
}

bool Greater(ll A, ll B) {
    return A > B;
}

bool LessOrEqual(ll A, ll B) {
    return A <= B;
}

bool GreaterOrEqual(ll A, ll B) {
    return A >= B;
}

const ld EPS = 1e-9;

bool Equal(ld A, ld B) {
    return abs(A - B) < EPS;
}

bool Less(ld A, ld B) {
    return A + EPS < B;
}

bool Greater(ld A, ld B) {
    return A > B + EPS;
}

bool LessOrEqual(ld A, ld B) {
    return A <= B + EPS;
}

bool GreaterOrEqual(ld A, ld B) {
    return A + EPS >= B;
}

template<typename T, typename Q>
bool LessOrEqual(T A, Q B) {
    using C = std::common_type_t<T, Q>;
    return LessOrEqual(static_cast<C>(A), static_cast<C>(B));
}

template<typename T, typename Q>
bool Equal(T A, Q B) {
    using C = std::common_type_t<T, Q>;
    return Equal(static_cast<C>(A), static_cast<C>(B));
}

template<typename T, typename Q>
bool Less(T A, Q B) {
    using C = std::common_type_t<T, Q>;
    return Less(static_cast<C>(A), static_cast<C>(B));
}

template<typename T, typename Q>
bool Greater(T A, Q B) {
    using C = std::common_type_t<T, Q>;
    return Greater(static_cast<C>(A), static_cast<C>(B));
}

template<typename T, typename Q>
bool GreaterOrEqual(T A, Q B) {
    using C = std::common_type_t<T, Q>;
    return GreaterOrEqual(static_cast<C>(A), static_cast<C>(B));
}

template<typename T>
ll sgn(T x) {
    if (Equal(x, 0)) return 0;
    return Less(x, 0) ? -1 : 1;
}


template<typename T>
struct Point {
    T x;
    T y;

    Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {}

    template<typename Q>
    Point(const Point<Q> &other) {
        x = static_cast<T>(other.x);
        y = static_cast<T>(other.y);
    }


    template<typename Q>
    Point(Point<Q> &&other) {
        x = static_cast<T>(other.x);
        y = static_cast<T>(other.y);
    }

    template<typename Q>
    Point<std::common_type_t<T, Q>> operator+(const Point<Q> &oth) const {
        return Point{x + oth.x, y + oth.y};
    }

    template<typename Q>
    Point<std::common_type_t<T, Q>> operator-(const Point<Q> &oth) const {
        return {x - oth.x, y - oth.y};
    }

    template<typename Q>
    bool operator==(const Point<Q> &oth) const {
        return x == oth.x && y == oth.y;
    }

    template<typename Q>
    bool operator<(const Point<Q> &oth) const {
        return make_pair(x, y) < make_pair(oth.x, oth.y);
    }

    template<typename Q>
    requires (is_integral_v<Q> || is_floating_point_v<Q>)
    Point<std::common_type_t<Q, T>> operator*(const Q &b) const {
        return {x * b, y * b};
    }


    template<typename Q>
    requires (is_integral_v<Q> || is_floating_point_v<Q>)
    Point<ld> operator/(const Q &b) const {
        return {(ld) x / b, (ld) y / b};
    }

    template<typename Q>
    std::common_type_t<Q, T> operator*(const Point<Q> &oth) const {
        return x * oth.y - y * oth.x;
    }

    template<typename Q>
    std::common_type_t<Q, T> operator%(const Point<Q> &oth) const {
        return x * oth.x + y * oth.y;
    }

    Point &operator+=(const Point &other) {
        x += other.x;
        y += other.y;
        return *this;
    }

    Point &operator-=(const Point &other) {
        x -= other.x;
        y -= other.y;
        return *this;
    }

    friend ostream &operator<<(ostream &stream, const Point &P) {
        stream << P.x << ' ' << P.y;
        return stream;
    }


    friend istream &operator>>(istream &stream, Point &P) {
        stream >> P.x >> P.y;
        return stream;
    }
};

template<typename T>
Point<T> rotateCW(const Point<T> &P) {
    return {P.y, -P.x};
}

template<typename T>
Point<T> rotateCCW(const Point<T> &P) {
    return {-P.y, P.x};
}

template<typename T, typename Q>
bool Equal(const Point<T> &a, const Point<Q> &b) {
    return Equal(a.x, b.x) && Equal(a.y, b.y);
}

template<typename T, typename Q>
bool Less(const Point<T> &a, const Point<Q> &b) {
    if (!Equal(a.x, b.x)) return Less(a.y, b.y);
    return Less(a.y, b.y);
}

template<typename T, typename Q>
bool Greater(const Point<T> &a, const Point<Q> &b) {
    if (!Equal(a.x, b.x)) return Greater(a.y, b.y);
    return Greater(a.y, b.y);
}

template<typename T>
Point<T> operator-(const Point<T> &a) {
    return {-a.x, -a.y};
}


template<typename T>
T len2(const Point<T> &a) {
    return a % a;
}

template<typename T>
ld len(const Point<T> &a) {
    return sqrtl(len2(a));
}

template<typename T, typename Q>
T dist2(const Point<T> &a, const Point<Q> &b) {
    return len2(a - b);
}

template<typename T, typename Q>
ld dist(const Point<T> &a, const Point<Q> &b) {
    return len(a - b);
}

using pt = Point<ll>;
using ptd = Point<ld>;

template<typename T = ld>
const Point<T> NULL_POINT = {T(-INFi - 1337), T(INFi + 228)};

template<typename T>
struct Segment;

template<typename T>
struct Ray;

template<typename T>
struct Line {
    T a, b, c;
    // ax + by = c


    template<class Q>
    Line(const Line<Q> &other) {
        a = other.a;
        b = other.b;
        c = other.c;
    }

    Line(const Point<T> &F, Point<T> V, bool isDirection = false) {
        if (!isDirection) {
            V -= F;
        }
        a = V.y;
        b = -V.x;
        c = a * F.x + b * F.y;
    }


    Line(const T &a1 = 0, const T &b1 = 0, const T &c1 = 0) {
        a = a1;
        b = b1;
        c = c1;
    }

    template<class Q>
    explicit Line(const Segment<Q> &other) : Line(other.A, other.B, false) {
    }

    template<class Q>
    explicit Line(const Ray<Q> &other) : Line(other.A, other.V, true) {
    }

    pair<ptd, ptd> GetPointAndDirection() const {
        ptd V = {-b, a};
        ptd A;
        if (!Equal(a, 0)) {
            A.y = 0;
            A.x = c / (ld) a;
        } else if (!Equal(b, 0)) {
            A.x = 0;
            A.y = c / (ld) b;
        } else {
            assert(0);
        }
        return {A, V};
    }

    template<class Q>
    ptd Proj(const Point<Q> &P) const {
        auto [A, V] = GetPointAndDirection();
        ld value = (P - A) % V;
        value /= (ld) len2(V);
        return ptd(A) + (ptd(V) * value);
    }

    template<class Q>
    bool Contains(const Point<Q> &P) const {
        return Equal(GetValue(P), c);
    }

    template<typename Q>
    ld Dist(const Point<Q> &P) const {
        return dist(Proj(P), P);
    }

    template<typename Q>
    std::common_type_t<Q, T> GetValue(const Point<Q> &P) const {
        return a * P.x + b * P.y;
    }

    friend ostream &operator<<(ostream &stream, const Line &L) {
        stream << L.a << ' ' << L.b << ' ' << L.c;
        return stream;
    }


    friend istream &operator>>(istream &stream, Line &L) {
        stream >> L.a >> L.b >> L.c;
        return stream;
    }
};


template<typename Q, typename U>
ld Dist(const Point<Q> &A, const Line<U> &line) {
    return line.Dist(A);
}

template<typename Q, typename U>
Point<ld> Intersect(const Line<Q> &line1, const Line<U> &line2) {
    using C = std::common_type_t<Q, U>;
    C det = line1.a * line2.b - line1.b * line2.a;
    if (Equal(det, 0)) return NULL_POINT<ld>;
    C detx = line1.c * line2.b - line1.b * line2.c;
    C dety = line1.a * line2.c - line1.c * line2.a;
    return {(ld) detx / (ld) det, (ld) dety / (ld) det};
}

template<typename Q, typename U>
bool IsParallel(const Line<Q> &line1, const Line<U> &line2) {
    return Equal(line1.a * line2.b - line1.b * line2.a, 0);
}

template<typename Q, typename U>
ld Dist(const Line<Q> &line1, const Line<U> &line2) {
    if (IsParallel(line1, line2)) {
        return line1.Dist(line2.A);
    }
    return 0;
}


template<typename T, typename U, typename V>
bool IsCollinear(const Point<T> &a, const Point<U> &b, const Point<V> &c) {
    return Equal((c - a) * (b - a), 0);
}

template<typename T, typename U, typename V>
bool IsInside(T L, U R, V P) {
    return LessOrEqual(L, P) && LessOrEqual(P, R);
}

template<typename T>
struct Segment {
    Point<T> A, B;

    Segment(const Point<T> &a = {0, 0}, const Point<T> &b = {0, 0}) : A(a), B(b) {
    }


    template<class Q>
    Segment(const Segment<Q> &other) : A(other.A), B(other.B) {
    }

    T len2() const {
        return dist2(A, B);
    }

    ld len() const {
        return dist(A, B);
    }

    template<class Q>
    bool Contains(const Point<Q> &P) const {
        if (!IsCollinear(A, B, P)) {
            return false;
        }
        return IsInside(min(A.x, B.x), max(A.x, B.x), P.x) && IsInside(min(A.y, B.y), max(A.y, B.y), P.y);
    }

    template<typename Q>
    ld Dist(const Point<Q> &P) const {
        ld answer = min(dist(P, A), dist(P, B));
        ptd Ap = Line<ld>(*this).Proj(P);
        if (Contains(Ap)) {
            answer = dist(Ap, P);
        }
        return answer;
    }
};


template<typename Q, typename U>
ld Dist(const Point<Q> A, const Segment<U> &seg) {
    return seg.Dist(A);
}


template<typename U, typename V>
bool isIntersected(const Segment<U> &seg1, const Segment<V> &seg2) {
    ll s1 = sgn((seg1.B - seg1.A) * (seg2.A - seg1.A)) * sgn((seg1.B - seg1.A) * (seg2.B - seg1.A));
    if (s1 > 0) return false;
    ll s2 = sgn((seg2.B - seg2.A) * (seg1.A - seg2.A)) * sgn((seg2.B - seg2.A) * (seg1.B - seg2.A));
    if (s2 > 0) return false;
    return s1 < 0 || s2 < 0 || seg1.Contains(seg2.A) || seg1.Contains(seg2.B) || seg2.Contains(seg1.A);
}

template<typename U, typename V>
ld Dist(const Segment<U> &seg1, const Segment<V> &seg2) {
    if (isIntersected(seg1, seg2)) {
        return 0;
    }
    return min(min(seg1.Dist(seg2.A), seg1.Dist(seg2.B)), min(seg2.Dist(seg1.A), seg2.Dist(seg1.B)));
}

template<typename U, typename V>
bool isIntersected(const Segment<U> &seg, const Line<V> &line) {
    return sgn((seg.A - line.A) * line.V) * sgn((seg.B - line.A) * line.V) <= 0;
}

template<typename Q, typename U>
ld Dist(const Segment<Q> &seg, const Line<U> &line) {
    if (isIntersected(seg, line)) {
        return 0;
    }
    return min(line.Dist(seg.A), line.Dist(seg.B));
}

template<typename T>
struct Ray {
    Point<T> A, V;

    Ray(const Point<T> &a = {0, 0}, const Point<T> &v = {1, 0}, bool isDirection = false) {
        if (isDirection) {
            A = a;
            V = v;
        } else {
            A = a;
            V = v - a;
        }
    }

    template<class Q>
    Ray(const Ray<Q> &other) : A(other.A), V(other.V) {
    }

    template<class Q>
    Ray(const Segment<Q> &other) : A(other.A), V(other.B - other.A) {
    }

    template<class Q>
    bool Contains(const Point<Q> &P) const {
        return Equal(V * (P - A), 0) && GreaterOrEqual(V % (P - A), 0);
    }

    template<typename Q>
    ld Dist(const Point<Q> &P) const {
        ld answer = dist(P, A);
        ptd Ap = Line<ld>(*this).Proj(P);
        if (Contains(Ap)) {
            answer = dist(Ap, P);
        }
        return answer;
    }
};


template<typename Q, typename U>
ld Dist(const Point<Q> A, const Ray<U> &ray) {
    return ray.Dist(A);
}


template<typename U, typename V>
bool isIntersected(const Segment<U> &seg, const Ray<V> &ray) {
    ll sA = sgn((seg.A - ray.A) * ray.V);
    ll sB = sgn((seg.B - ray.A) * ray.V);
    if (sA * sB > 0) return false;
    if (sA == 0 || sB == 0) return ray.Contains(seg.A) || ray.Contains(seg.B);
    ll sAB = sgn((seg.A - ray.A) * (seg.B - ray.A));
    return sAB == 0 || sAB == sA;
}


template<typename U, typename V>
ld Dist(const Segment<U> &seg, const Ray<V> &ray) {
    if (isIntersected(seg, ray)) {
        return 0;
    }
    return min(min(ray.Dist(seg.A), ray.Dist(seg.B)), seg.Dist(ray.A));
}


template<typename U, typename V>
bool isIntersected(const Ray<U> &ray1, const Ray<V> &ray2) {
    auto mid = Intersect(Line<U>(ray1), Line<V>(ray2));
    if (ray1.Contains(mid) && ray2.Contains(mid)) return true;
    return ray1.Contains(ray2.A) || ray2.Contains(ray1.A);
}

template<typename U, typename V>
ld Dist(const Ray<U> &ray1, const Ray<V> &ray2) {
    if (isIntersected(ray1, ray2)) {
        return 0;
    }
    return min(ray1.Dist(ray2.A), ray2.Dist(ray1.A));
}

template<typename U, typename V>
bool isIntersected(const Ray<U> &ray, const Line<V> &line) {
    auto mid = Intersect(Line<U>(ray), line);
    if (ray.Contains(mid)) return true;
    return line.Contains(ray.A);
}

template<typename U, typename V>
ld Dist(const Ray<U> &ray, const Line<V> &line) {
    if (isIntersected(ray, line)) {
        return 0;
    }
    return line.Dist(ray.A);
}

const ld PI = atan2(0, -1);

template<typename T = ld>
struct Circle {
    Point<T> O;
    T R;

    Circle(const Point<T> &o = {0, 0}, const T &r = 0) : O(o), R(r) {}

    template<typename Q>
    Circle(const Circle<Q> &other) : O(other.O), R(other.R) {}

    template<typename Q>
    Circle(Circle<Q> &&other) : O(other.O), R(other.R) {}

    ld Area() const {
        return R * R * PI;
    }


    template<typename U, typename V>
    Point<ld> GetCircleCenterWithZero(const Point<U> &b,
                                      const Point<V> &c) {
        ld B = len2(b);
        ld C = len2(c);
        ld D = b * c;
        return {(c.y * B - b.y * C) / (2 * D),
                (b.x * C - c.x * B) / (2 * D)};
    }

    template<typename U, typename V, typename W>
    Circle(const Point<U> &A, const Point<V> &B,
           const Point<W> &C) {
        static_assert(std::is_same_v<T, ld>);
        O = GetCircleCenterWithZero(B - A, C - A);
        R = len(O);
        O += A;
    }

    template<typename U, typename V>
    Circle(const Point<U> &A, const Point<V> &B) {
        static_assert(std::is_same_v<T, ld>);
        O = (A + B) / (ld) 2;
        R = (ld) dist(A, B) / (ld) 2;
    }

    template<typename U>
    bool isInside(const Point<U> &P) const {
        return LessOrEqual(dist(P, O), R);
    }
};

// return (L, R) points in counter-clock-wise order related circle1
// if no intersect or coincide return (NULL_POINT, NULL_POINT)
template<typename T, typename U>
pair<Point<ld>, Point<ld>> Intersect(const Circle<T> &circle1, const Circle<U> &circle2) {
    if (Equal(circle1.O, circle2.O) && Equal(circle2.R, circle1.R)) return {NULL_POINT<ld>, NULL_POINT<ld>};
    auto d2 = dist2(circle2.O, circle1.O);
    if (Equal(d2, 0)) return {NULL_POINT<ld>, NULL_POINT<ld>};
    if (Less((circle1.R + circle2.R) * (circle2.R + circle1.R), d2) ||
        Less(d2, (circle1.R - circle2.R) * (circle1.R - circle2.R)))
        return {NULL_POINT<ld>, NULL_POINT<ld>};
    ld d = sqrtl(d2);
    ld A = (d2 - circle2.R * circle2.R + circle1.R * circle1.R) / (2 * d);
    ld B = sqrtl(max((ld) 0, circle1.R * circle1.R - A * A));
    Point<ld> V = (circle2.O - circle1.O) / d;
    Point<ld> M = circle1.O + V * A;
    V = rotateCCW(V) * B;
    return {M - V, M + V};
}

template<typename T, typename U>
pair<Point<ld>, Point<ld>> Intersect(const Circle<T> &circle, const Line<U> &line) {
    auto [a, b] = line.GetPointAndDirection();
    a -= circle.O;
    auto A = len2(b);
    auto B = a % b;
    auto C = len2(a) - circle.R * circle.R;
    auto D = B * B - A * C;
    if (Less(D, 0)) return {NULL_POINT<ld>, NULL_POINT<ld>};
    if (D < 0) D = 0;
    Point<ld> result = circle.O + a;
    return {result + b * (-B + sqrtl(D)) / (ld) A,
            result + b * (-B - sqrtl(D)) / (ld) A};
}

template<typename U, typename V>
ld IntersectionArea(const Circle<U> &circle1, const Circle<V> &circle2) {
    ld d = dist(circle1.O, circle2.O);
    if (GreaterOrEqual(d, circle1.R + circle2.R)) {
        return 0;
    }
    if (LessOrEqual(d + circle1.R, circle2.R)) {
        return circle1.Area();
    }
    if (LessOrEqual(d + circle2.R, circle1.R)) {
        return circle2.Area();
    }
    ld alpha = acos((circle1.R * circle1.R + d * d - circle2.R * circle2.R) / (2 * circle1.R * d)) * 2;
    ld beta = acos((circle2.R * circle2.R + d * d - circle1.R * circle1.R) / (2 * circle2.R * d)) * 2;
    return 0.5 * circle2.R * circle2.R * (beta - sin(beta)) +
           0.5 * circle1.R * circle1.R * (alpha - sin(alpha));
}


template<typename U, typename V>
ld UnionArea(const Circle<U> &circle1, const Circle<V> &circle2) {
    return circle1.Area() + circle2.Area() - IntersectionArea(circle1, circle2);
}

mt19937 rng(123212);

template<typename T, typename U>
bool IsContainsPoints(const Circle<T> &c, const vector<Point<U>> &pts) {
    for (auto &p: pts) {
        if (!c.isInside(p)) {
            return false;
        }
    }
    return true;
}

template<typename T>
Circle<ld> MinCircle(vector<Point<T>> &pts) {
    int n = pts.size();
    Circle<ld> C(pts[0], (ld) 0);
    for (int i = 1; i < n; i++) {
        if (!C.isInside(pts[i])) {
            C = Circle<ld>(pts[i], (ld) 0);
            for (int j = 0; j < i; j++) {
                if (!C.isInside(pts[j])) {
                    C = Circle<ld>(pts[i], pts[j]);
                    for (int k = 0; k < j; k++) {
                        if (!C.isInside(pts[k])) {
                            C = Circle<ld>(pts[i], pts[j], pts[k]);
                        }
                    }
                }
            }
        }
    }
    return C;
}


template<typename T>
vector<Point<T>> ConvexHull(vector<Point<T>> pts) {
    int min_idx = min_element(all(pts)) - pts.begin();
    swap(pts[0], pts[min_idx]);

    sort(pts.begin() + 1, pts.end(), [&](const Point<T> &a, const Point<T> &b) {
        auto val = (a - pts[0]) * (b - pts[0]);
        if (val != 0) return val > 0;
        return dist2(a, pts[0]) < dist2(b, pts[0]);
    });
    vector<Point<T>> convex_hull = {pts[0]};
    int sz = 0;
    for (int i = 1; i < (int) pts.size(); ++i) {
        while (sz && LessOrEqual((convex_hull[sz] - convex_hull[sz - 1]) * (pts[i] - convex_hull[sz]), 0)) {
            convex_hull.pop_back();
            --sz;
        }
        convex_hull.push_back(pts[i]);
        ++sz;
    }
    return convex_hull;
}

template<typename T, typename U>
bool VComp(const Point<T> &a, const Point<U> &b) {
    bool upA = a.y > 0 || (a.y == 0 && a.x >= 0);
    bool upB = b.y > 0 || (b.y == 0 && b.x >= 0);
    if (upA != upB) return upA;
    auto val = a * b;
    if (val != 0) return val > 0;
    return len2(a) < len2(b);
}

template<typename T, typename U>
bool VCompNoLen(const Point<T> &a, const Point<U> &b) {
    bool upA = a.y > 0 || (a.y == 0 && a.x >= 0);
    bool upB = b.y > 0 || (b.y == 0 && b.x >= 0);
    if (upA != upB) return upA;
    auto val = a * b;
    return val > 0;
}

template<typename T>
T SignedArea(vector<Point<T>> &pts) {
    int n = pts.size();
    T res = 0;
    rep(i, n) {
        res += pts[i] * pts[(i + 1) % n];
    }
    return res;
}

template<typename T>
T Area(vector<Point<T>> &pts) {
    return abs(SignedArea(pts));
}


template<typename T>
void NormalizeConvexPoly(vector<Point<T>> &A) {
    if (SignedArea(A) < 0) {
        reverse(all(A));
    }
    int min_idx = min_element(all(A), [&](const Point<T> &a, const Point<T> &b) {
        return make_pair(a.y, a.x) < make_pair(b.y, b.x);
    }) - A.begin();
    rotate(A.begin(), A.begin() + min_idx, A.end());
}

template<typename T>
vector<Point<T>> MinkowskiSum(vector<Point<T>> A, vector<Point<T>> B) {
    NormalizeConvexPoly(A);
    NormalizeConvexPoly(B);
    if (A.empty()) return B;
    if (B.empty()) return A;
    Point<T> S = A[0] + B[0];
    vector<Point<T>> edges;
    int n = A.size(), m = B.size();
    rep(i, n) edges.push_back(A[(i + 1) % n] - A[i]);
    rep(i, m) edges.push_back(B[(i + 1) % m] - B[i]);
    sort(all(edges), VComp<T, T>);
    rotate(edges.begin(), edges.end() - 1, edges.end());
    edges[0] = S;
    for (int i = 1; i < edges.size(); ++i) {
        edges[i] += edges[i - 1];
    }
    return edges;
}

template<typename T>
ld DistConvexPolygons(const vector<Point<T>> &A, vector<Point<T>> B) {
    for (auto &p: B) p = -p;
    auto C = MinkowskiSum(A, B);
    NormalizeConvexPoly(C);
    int n = C.size();
    bool ok = true;
    rep(i, n) ok &= ((C[i] * C[(i + 1) % n]) >= 0);
    if (ok) return 0;
    Point<T> mid(0, 0);
    ld d = dist(mid, C[0]);
    rep(i, n) d = min(d, Dist(mid, Segment(C[(i + 1) % n], C[i])));
    return d;
}


template<typename T, typename U>
pair<int, int> GetTangents(const vector<Point<T>> &poly, const Line<U> &line) {
    int n = poly.size();
    auto start = line.GetValue(poly[0]);
    bool isUp = line.GetValue(poly[1]) >= start;
    pair<int, int> result = {-1, -1};
    if (isUp) {
        result.first = FindLastFalse(0, n, [&](const int &i) {
            if (!i) return false;
            auto val = line.GetValue(poly[i]);
            if (val < start) return true;
            auto valp = line.GetValue(poly[i - 1]);
            if (valp > val) return true;
            return false;
        });
        result.second = FindLastFalse(0, n, [&](const int &i) {
            if (i <= 1) return false;
            auto val = line.GetValue(poly[i]);
            if (val >= start) return false;
            auto valp = line.GetValue(poly[i - 1]);
            if (valp < val) return true;
            return false;
        });
    } else {
        result.first = FindLastFalse(0, n, [&](const int &i) {
            if (i <= 1) return false;
            auto val = line.GetValue(poly[i]);
            if (val <= start) return false;
            auto valp = line.GetValue(poly[i - 1]);
            if (valp > val) return true;
            return false;
        });
        result.second = FindLastFalse(0, n, [&](const int &i) {
            if (!i) return false;
            auto val = line.GetValue(poly[i]);
            if (val > start) return true;
            auto valp = line.GetValue(poly[i - 1]);
            if (valp < val) return true;
            return false;
        });
    }
    for (int i: {0, 1, n - 2, n - 1}) {
        if (i < 0 || i >= (int) poly.size()) continue;
        if (line.GetValue(poly[result.first]) < line.GetValue(poly[i])) result.first = i;
        if (line.GetValue(poly[result.second]) > line.GetValue(poly[i])) result.second = i;
    }
    return result;
}

template<typename T, typename U>
pair<int, int> GetTangents(const vector<Point<T>> &poly, const Point<U> &P) {
    int n = poly.size();
    auto GetDirection = [&](int i, int j) {
        if (i < 0) i += n;
        if (j < 0) j += n;
        if (i >= n) i -= n;
        if (j >= n) j -= n;
        if (i == j) return 0;
        auto val = (poly[i] - P) * (poly[j] - P);
        if (val > 0) return -2;
        if (val < 0) return 2;
        auto q = dist2(poly[i], P) - dist2(poly[j], P);
        if (q > 0) return -1;
        if (q < 0) return 1;
        assert(false);
        return 0;
    };
    ll d01 = GetDirection(0, 1);
    pair<int, int> result = {-1, -1};
    if (d01 == -1) {
        result.first = 0;
    } else if (d01 == -2) {
        result.first = FindFirstTrue(0, n, [&](const int &i) {
            if (!i) return false;
            if (GetDirection(0, i) >= -1) return true;
            if (GetDirection(i, i + 1) == -2) return false;
            return true;
        }) % n;
    } else {
        assert(d01 == 1 || d01 == 2);
        result.first = FindFirstTrue(0, n, [&](const int &i) {
            ll v = GetDirection(0, i);
            assert(v != -1);
            if (v >= 2) return false;
            if (GetDirection(i, i + 1) == -2) return false;
            return true;
        }) % n;
    }
    assert(GetDirection(result.first, result.first + 1) >= -1 && GetDirection(result.first, result.first - 1) >= -1);
    if (d01 == 1) {
        result.second = 1;
    } else if (d01 == 2) {
        result.second = FindFirstTrue(0, n, [&](const int &i) {
            if (!i) return false;
            if (GetDirection(0, i) <= 1) return true;
            if (GetDirection(i, i + 1) >= 1) return false;
            return true;
        }) % n;
    } else {
        assert(d01 == -1 || d01 == -2);
        result.second = FindFirstTrue(0, n, [&](const int &i) {
            if (!i) return false;
            ll v = GetDirection(0, i);
            assert(v != 1);
            if (v <= -2) return false;
            if (GetDirection(i, i + 1) >= 1) return false;
            return true;
        }) % n;
    }
    assert(GetDirection(result.second, result.second + 1) <= 1 && GetDirection(result.second, result.second - 1) <= 1);
    return result;
}

using int128 = __int128;

ll AreaTriangle(pt a, pt b, pt c) {
    return abs((b - a) * (c - a));
}

void solve() {
    int n;
    cin >> n;
    pt O;
    ll R;
    cin >> O >> R;
    vector<pt> a(n);
    rep(i, n) cin >> a[i];
    int j = 0;
    ll area = 0;
    ll ans = 0;
    rep(i, n) {
        j = max(j, i + 1);
        while (j + 1 < i + n) {
            // (i, j, j + 1)
            pt A = a[i];
            pt B = a[j % n];
            pt C = a[(j + 1) % n];
            int128 s = (C - A) * (O - A);
            if (s < 0) {
                break;
            }
            int128 d2 = len2((C - A));
            if (s * s < d2 * R * R) {
                break;
            }
            area += AreaTriangle(A, B, C);
            j++;
        }
        ckmax(ans, area);
        area -= AreaTriangle(a[i], a[(i + 1) % n], a[j % n]);
    }
    cout << ans << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout << setprecision(12) << fixed;
    int t = 1;
    cin >> t;
    rep(i, t) {
        solve();
    }
    return 0;
}

这程序好像有点Bug,我给组数据试试?

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3572kb

input:

3
5
1 1 1
0 0
1 0
5 0
3 3
0 5
6
2 4 1
2 0
4 0
6 3
4 6
2 6
0 3
4
3 3 1
3 0
6 3
3 6
0 3

output:

5
24
0

result:

ok 3 number(s): "5 24 0"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3584kb

input:

1
6
0 0 499999993
197878055 -535013568
696616963 -535013568
696616963 40162440
696616963 499999993
-499999993 499999993
-499999993 -535013568

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 10ms
memory: 3584kb

input:

6666
19
-142 -128 26
-172 -74
-188 -86
-199 -157
-200 -172
-199 -186
-195 -200
-175 -197
-161 -188
-144 -177
-127 -162
-107 -144
-90 -126
-87 -116
-86 -104
-89 -97
-108 -86
-125 -80
-142 -74
-162 -72
16
-161 -161 17
-165 -190
-157 -196
-154 -197
-144 -200
-132 -200
-128 -191
-120 -172
-123 -163
-138...

output:

5093
3086
2539
668
3535
7421
4883
5711
5624
1034
2479
3920
4372
2044
4996
5070
2251
4382
4175
1489
1154
3231
4038
1631
5086
14444
1692
6066
687
1512
4849
5456
2757
8341
8557
8235
1013
5203
10853
6042
6300
4480
2303
2728
1739
2187
3385
4266
6322
909
4334
1518
948
5036
1449
2376
3180
4810
1443
1786
47...

result:

ok 6666 numbers

Test #4:

score: 0
Accepted
time: 15ms
memory: 3684kb

input:

6660
19
-689502500 -712344644 121094647
-534017213 -493851833
-578925616 -506634533
-663335128 -540066520
-748890119 -585225068
-847722967 -641694086
-916653030 -716279342
-956235261 -766049951
-1000000000 -836145979
-963288744 -923225928
-948140134 -944751289
-920681768 -972760883
-872492254 -10000...

output:

117285633945667137
89094762176992129
84336379088082383
63629451600307531
193020267813347512
73921930794195237
59524748406448173
34419869321856821
207356845785317033
185783506654647921
80463327658075813
156569165998743736
129550296314602340
157065066097450631
77819745596643484
40796197589680466
11394...

result:

ok 6660 numbers

Test #5:

score: 0
Accepted
time: 15ms
memory: 3644kb

input:

6646
17
-822557900 -719107452 81678600
-810512657 -985436857
-717822260 -1000000000
-636451281 -949735403
-599009378 -915571539
-596352662 -824307789
-736572772 -553995003
-765031367 -500309996
-797636289 -458500641
-842827212 -428669086
-871078362 -428977078
-928761972 -490982466
-999825512 -570408...

output:

110526056201314429
15027921575542560
53254517372894023
258485758440262622
34392829191543913
76614213562057620
145259866156654928
42339731416270977
143102643161355094
106105394104280855
145392090901459236
43856914998019051
173982988807640937
44231578293584008
58978505810355496
23485666110810764
12532...

result:

ok 6646 numbers

Test #6:

score: 0
Accepted
time: 19ms
memory: 3680kb

input:

6669
15
-874867377 -757943357 7111757
-974567193 -807217609
-949619167 -890139925
-934615014 -930145748
-888846948 -960741232
-795467329 -1000000000
-722124377 -940364550
-622857698 -842665231
-578818283 -747428314
-780030596 -534753737
-866558348 -484345048
-928090924 -519994734
-987269004 -5856231...

output:

182950707425830089
29338404516797685
84520746595092394
105477320399449524
73884037892247358
49031829753894899
48108760133499810
178434777514737858
31287633742235961
84173958668093920
15282003310382472
106987783997819044
50751134064267722
22920035202317059
79797616191974237
75995194318427644
94277118...

result:

ok 6669 numbers

Test #7:

score: 0
Accepted
time: 15ms
memory: 3588kb

input:

6673
11
-746998467 -874016929 25938500
-1000000000 -901415571
-645111069 -992353393
-547811885 -1000000000
-483640464 -931109189
-546643988 -877114659
-625764830 -834162211
-723093733 -813353581
-811419393 -799116488
-879584543 -791576283
-944145006 -828676656
-998000881 -880308971
14
-826271552 -81...

output:

54570343814105147
74950556637655098
38052401037814742
109159348998561498
21083015515232346
31649646072675313
42326841119894707
158636477858979605
129690295986443039
112077348808529800
16900062518936042
63732368902300348
79182769273740625
142098431062104007
111981825046535522
38580332981675983
631960...

result:

ok 6673 numbers

Test #8:

score: 0
Accepted
time: 16ms
memory: 4628kb

input:

1
100000
312059580 -177336163 523906543
43599219 998132845
43570757 998134606
43509809 998138374
43456461 998141672
43379797 998146410
43325475 998149757
43283580 998152335
43207966 998156986
43131288 998161701
43054854 998166387
42988614 998170421
42922795 998174418
42844022 998179189
42778015 9981...

output:

2336396422009996549

result:

ok 1 number(s): "2336396422009996549"

Test #9:

score: 0
Accepted
time: 16ms
memory: 4628kb

input:

1
100000
-251564816 -78082096 448753841
-80224677 990816180
-80259466 990812190
-80305475 990806906
-80353208 990801417
-80432095 990792336
-80499807 990784538
-80550474 990778690
-80584379 990774772
-80646058 990767643
-80721039 990758969
-80765340 990753844
-80831878 990746146
-80884094 990740100
...

output:

2228503226896114609

result:

ok 1 number(s): "2228503226896114609"

Test #10:

score: 0
Accepted
time: 16ms
memory: 4652kb

input:

1
100000
-21114562 65507992 38717262
185741374 -973388860
185752671 -973385638
185780414 -973377719
185856314 -973356051
185933967 -973333881
185954554 -973328000
186032784 -973305637
186080608 -973291964
186146989 -973272982
186174716 -973265053
186244761 -973245018
186322991 -973222629
186396908 -...

output:

3072519712977372770

result:

ok 1 number(s): "3072519712977372770"

Test #11:

score: 0
Accepted
time: 16ms
memory: 4620kb

input:

1
100000
268671 -2666521 876866632
230011647 -961116491
230075890 -961094782
230134968 -961074817
230168748 -961063401
230244475 -961037808
230269796 -961029249
230315761 -961013704
230385411 -960990142
230415463 -960979975
230481755 -960957543
230553370 -960933304
230586681 -960922029
230613411 -96...

output:

133463776650326652

result:

ok 1 number(s): "133463776650326652"

Test #12:

score: 0
Accepted
time: 16ms
memory: 4632kb

input:

1
100000
-2718704 778274 581723239
-978709486 169949360
-978714995 169927878
-978732247 169860576
-978751379 169785908
-978765698 169730020
-978773095 169701140
-978776354 169688400
-978789899 169635448
-978801355 169590640
-978818799 169522411
-978836755 169452110
-978848869 169404635
-978865973 16...

output:

868255658642677668

result:

ok 1 number(s): "868255658642677668"

Test #13:

score: 0
Accepted
time: 12ms
memory: 4800kb

input:

1
100000
-2748577 -2474335 98902294
951770249 -240991282
951794130 -240924574
951808902 -240883307
951834639 -240811406
951854284 -240756524
951859830 -240741030
951881397 -240680772
951908083 -240606202
951935455 -240529694
951945987 -240500253
951973326 -240423829
951997817 -240355366
952015600 -2...

output:

2586612861573259216

result:

ok 1 number(s): "2586612861573259216"

Extra Test:

score: 0
Extra Test Passed