QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#598860 | #9434. Italian Cuisine | ucup-team133# | WA | 26ms | 3620kb | C++23 | 10.6kb | 2024-09-28 23:44:09 | 2024-09-28 23:44:09 |
Judging History
answer
#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif
template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
for (auto& e : v) {
is >> e;
}
return is;
}
template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
for (std::string_view sep = ""; const auto& e : v) {
os << std::exchange(sep, " ") << e;
}
return os;
}
template <class T, class U = T> bool chmin(T& x, U&& y) {
return y < x and (x = std::forward<U>(y), true);
}
template <class T, class U = T> bool chmax(T& x, U&& y) {
return x < y and (x = std::forward<U>(y), true);
}
template <class T> void mkuni(std::vector<T>& v) {
std::ranges::sort(v);
auto result = std::ranges::unique(v);
v.erase(result.begin(), result.end());
}
template <class T> int lwb(const std::vector<T>& v, const T& x) {
return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}
#include <type_traits>
namespace geometry {
template <typename T> struct Point {
static T EPS;
static void set_eps(T eps) { EPS = eps; }
T x, y;
Point() {}
Point(T x, T y) : x(x), y(y) {}
Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
Point operator*(T t) const { return Point(x * t, y * t); }
Point operator/(T t) const { return Point(x / t, y / t); }
bool operator==(const Point& p) const { return x == p.x and y == p.y; }
bool operator!=(const Point& p) const { return not((*this) == p); }
bool operator<(const Point& p) const { return x != p.x ? x < p.x : y < p.y; }
friend std::istream& operator>>(std::istream& is, Point& p) { return is >> p.x >> p.y; }
friend std::ostream& operator<<(std::ostream& os, const Point& p) { return os << p.x << ' ' << p.y; }
T norm() { return std::sqrt(x * x + y * y); }
T norm2() { return x * x + y * y; }
T arg() { return std::atan2(y, x); }
T dot(const Point& p) { return x * p.x + y * p.y; }
T det(const Point& p) { return x * p.y - y * p.x; }
Point perp() { return Point(-y, x); }
Point unit() { return *this / norm(); }
Point normal() { return perp().unit(); }
Point rotate(T rad) { return Point(std::cos(rad) * x - std::sin(rad) * y, std::sin(rad) * x + std::cos(rad) * y); }
};
template <> double Point<double>::EPS = 1e-9;
template <> long double Point<long double>::EPS = 1e-12;
template <> int Point<int>::EPS = 0;
template <> long long Point<long long>::EPS = 0;
template <typename T> int sgn(T x) { return x < -Point<T>::EPS ? -1 : x > Point<T>::EPS ? 1 : 0; }
} // namespace geometry
namespace geometry {
template <typename T> struct Circle {
Point<T> c;
T r;
Circle() {}
Circle(Point<T> c, T r) : c(c), r(r) {}
friend std::istream& operator>>(std::istream& is, Circle& c) { return is >> c.c >> c.r; }
friend std::ostream& operator<<(std::ostream& os, const Circle& c) { return os << c.c << ' ' << c.r; }
};
} // namespace geometry
namespace geometry {
enum Position { COUNTER_CLOCKWISE = +1, CLOCKWISE = -1, ONLINE_BACK = +2, ONLINE_FRONT = -2, ON_SEGMENT = 0 };
template <typename T> Position ccw(const Point<T>& a, Point<T> b, Point<T> c) {
b = b - a;
c = c - a;
if (sgn(b.det(c)) == 1) return COUNTER_CLOCKWISE;
if (sgn(b.det(c)) == -1) return CLOCKWISE;
if (sgn(b.dot(c)) == -1) return ONLINE_BACK;
if (b.norm2() < c.norm2()) return ONLINE_FRONT;
return ON_SEGMENT;
}
} // namespace geometry
namespace geometry {
template <typename T> struct Polygon : std::vector<Point<T>> {
using std::vector<Point<T>>::vector;
Polygon(int n) : std::vector<Point<T>>(n) {}
T area2() {
T sum = 0;
int n = this->size();
for (int i = 0; i < n; i++) sum += (*this)[i].det((*this)[i + 1 == n ? 0 : i + 1]);
return sum < 0 ? -sum : sum;
}
T area() { return area2() / 2; }
bool is_convex() {
int n = this->size();
for (int j = 0; j < n; j++) {
int i = (j == 0 ? n - 1 : j - 1), k = (j == n - 1 ? 0 : j + 1);
if (ccw((*this)[i], (*this)[j], (*this)[k]) == CLOCKWISE) return false;
}
return true;
}
};
} // namespace geometry
namespace geometry {
template <typename T> struct Line {
Point<T> a, b;
Line() {}
Line(const Point<T>& a, const Point<T>& b) : a(a), b(b) {}
// A * x + B * y + C = 0
Line(T A, T B, T C) {}
friend std::istream& operator>>(std::istream& is, Line& l) { return is >> l.a >> l.b; }
friend std::ostream& operator<<(std::ostream& os, const Line& l) { return os << l.a << " to " << l.b; }
};
template <typename T> struct Segment : Line<T> {
Segment() {}
Segment(const Point<T>& a, const Point<T>& b) : Line<T>(a, b) {}
};
} // namespace geometry
namespace geometry {
template <typename T> Point<T> projection(const Line<T>& l, const Point<T>& p) {
Point<T> a = p - l.a, b = l.b - l.a;
return l.a + b * a.dot(b) / b.norm2();
}
} // namespace geometry
namespace geometry {
template <typename T> bool is_parallel(const Line<T>& l, const Line<T>& m) {
return sgn((l.b - l.a).det(m.b - m.a)) == 0;
}
template <typename T> bool is_orthogonal(const Line<T>& l, const Line<T>& m) {
return sgn((l.b - l.a).dot(m.b - m.a)) == 0;
}
template <typename T> bool has_crosspoint(const Segment<T>& s, const Segment<T>& t) {
return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 and ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
template <typename T> int count_common_tangent(const Circle<T>& c, const Circle<T>& d) {
T dist = (c.c - d.c).norm();
int tmp = sgn(dist - (c.r + d.r));
if (tmp > 0) return 4;
if (tmp == 0) return 3;
tmp = sgn(dist - (sgn(c.r - d.r) > 0 ? c.r - d.r : d.r - c.r));
if (tmp > 0) return 2;
if (tmp == 0) return 1;
return 0;
}
template <typename T> Point<T> crosspoint(const Line<T>& l, const Line<T>& m) {
assert(not is_parallel(l, m));
Point<T> u = l.b - l.a, v = m.b - m.a;
return l.a + u * v.det(m.a - l.a) / v.det(u);
}
template <typename T> Point<T> crosspoint(const Segment<T>& s, const Segment<T>& t) {
assert(has_crosspoint(s, t));
if (not is_parallel(s, t)) return crosspoint(Line(s.a, s.b), Line(t.a, t.b));
std::vector<Point<T>> v = {s.a, s.b, t.a, t.b};
for (int i = 0; i <= 2; i++) {
for (int j = 2; j >= i; j--) {
if (v[j + 1] < v[j]) {
std::swap(v[j], v[j + 1]);
}
}
}
return v[1];
}
template <typename T> std::vector<Point<T>> crosspoint(const Circle<T>& c, const Line<T>& l) {
Point<T> h = projection(l, c.c);
T x = c.r * c.r - (c.c - h).norm2();
if (sgn(x) < 0) return {};
if (sgn(x) == 0) return {h};
Point<T> v = (l.b - l.a).unit() * std::sqrt(x);
return {h - v, h + v};
}
template <typename T> std::vector<Point<T>> crosspoint(const Circle<T>& c, const Segment<T>& s) {}
template <typename T> std::vector<Point<T>> crosspoint(const Circle<T>& c1, const Circle<T>& c2) {
T r1 = c1.r, r2 = c2.r;
if (r1 < r2) return crosspoint(c2, c1);
T d = (c2.c - c1.c).norm();
if (sgn(d - (r1 + r2)) > 0 or sgn(d - (r1 - r2)) < 0) return {};
Point<T> v = c2.c - c1.c;
if (sgn(d - (r1 + r2)) == 0 or sgn(d - (r1 - r2)) == 0) return {c1.c + v.unit() * r1};
T p = ((r1 * r1 - r2 * r2) / d + d) / 2, q = std::sqrt(r1 * r1 - p * p);
Point<T> h = c1.c + v.unit() * p;
Point<T> i = v.normal();
return {h + i * q, h - i * q};
}
} // namespace geometry
namespace geometry {
template <typename T> T distance(const Point<T>& p, const Point<T>& q) { return (p - q).norm(); }
template <typename T> T distance(const Line<T>& l, const Point<T>& p) { return distance(p, projection(l, p)); }
template <typename T> T distance(const Segment<T>& s, const Point<T>& p) {
Point<T> h = projection(s, p);
return ccw(s.a, s.b, h) == ON_SEGMENT ? distance(p, h) : std::min(distance(p, s.a), distance(p, s.b));
}
template <typename T> T distance(const Segment<T>& s, const Segment<T>& t) {
return has_crosspoint(s, t) ? 0
: std::min({distance(s, t.a), distance(s, t.b), distance(t, s.a), distance(t, s.b)});
}
} // namespace geometry
using ll = long long;
using namespace std;
using namespace geometry;
void solve() {
int n;
cin >> n;
Circle<ll> c;
cin >> c;
vector<int> x(n), y(n);
for (int i = 0; i < n; i++) cin >> x[i] >> y[i];
Polygon<long double> p;
Polygon<ll> q;
for (int i = 0; i < n; i++) {
p.emplace_back(x[i], y[i]);
q.emplace_back(x[i], y[i]);
}
vector<ll> area(2 * n);
for (int i = 0; i < 2 * n; i++) area[i] = q[i % n].det(q[(i + 1) % n]);
vector<ll> sum(2 * n + 1);
sum[0] = 0;
for (int i = 0; i < 2 * n; i++) sum[i + 1] = sum[i] + area[i];
auto calc = [&](int l, int r) -> ll {
int R = (r < l ? r + n : r);
if (R - l < 2) return 0;
ll res = sum[R] - sum[l];
res += q[r].det(q[l]);
return abs(res);
};
auto check = [&](int i,int j) -> bool {
__int128_t a = (y[j] - y[i]), b = -(x[j] - x[i]), coef = - x[i] * (y[j] - y[i]) + y[i] * (x[j] - x[i]);
return (a * c.c.x + b * c.c.y + coef) * (a * c.c.x + b * c.c.y + coef) < (a*a + b*b) * (c.r*c.r);
};
ll ans = 0;
for (int i = 0; i < n; i++) {
{
int lb = 1, ub = n;
while (ub - lb > 1) {
int mid = (lb + ub) >> 1;
(ccw(q[i], c.c, q[(i + mid) % n]) != COUNTER_CLOCKWISE and
!check(i, (i+mid) % n)
? lb
: ub) = mid;
}
chmax(ans, calc(i, (i + lb) % n));
}
{
int lb = 0, ub = n - 1;
while (ub - lb > 1) {
int mid = (lb + ub) >> 1;
(ccw(q[i], c.c, q[(i + mid) % n]) != CLOCKWISE and !check(i,(i+mid) % n)
? ub
: lb) = mid;
}
chmax(ans, calc((i + ub) % n, i));
}
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
int T;
cin >> T;
for (; T--;) solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3620kb
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: 3472kb
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: 23ms
memory: 3544kb
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: -100
Wrong Answer
time: 26ms
memory: 3580kb
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:
218794780910418445 104698490127369465 112300060180132306 115365686523194212 218622087551180497 139975567090114140 83644889071922723 151227052438571182 207356845785317033 346120756606844756 90719848828123706 184117974332916352 146633002481785612 157065066097450631 104215990579366813 75345672469646794...
result:
wrong answer 1st numbers differ - expected: '117285633945667137', found: '218794780910418445'