QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#372699 | #5111. Take On Meme | shepherd | RE | 225ms | 47712kb | C++20 | 5.7kb | 2024-03-31 17:39:51 | 2024-03-31 17:39:53 |
Judging History
answer
#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#ifdef LLOCAL
#include "debug.h"
#else
#define var(...)
#define debugArr(...)
#endif
using namespace std;
#define len(a) static_cast<int>((a).size())
#define present(c, x) (c.find(x) != c.end())
#define printDecimal(d) std::cout << std::setprecision(d) << std::fixed
using ll = long long;
using ull = unsigned long long;
using ld = long double;
constexpr const int iinf = 1e9 + 7;
constexpr const ll inf = 1e18;
constexpr const ll mod = 1'000'000'007;
template <typename Fun>
class y_combinator_result {
Fun fun_;
public:
template <typename T>
explicit y_combinator_result(T&& fun) : fun_(std::forward<T>(fun)) {}
template <typename... Args>
decltype(auto) operator()(Args&&... args) {
return fun_(std::ref(*this), std::forward<Args>(args)...);
}
};
template <typename Fun>
decltype(auto) y_combinator(Fun&& fun) {
return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
}
template <class T>
int sgn(T x) {
return (x > 0) - (x < 0);
}
template <class T>
struct Point {
typedef Point P;
T x, y;
explicit Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {}
bool operator<(P p) const { return tie(x, y) < tie(p.x, p.y); }
bool operator==(P p) const { return tie(x, y) == tie(p.x, p.y); }
P operator+(P p) const { return P(x + p.x, y + p.y); }
P operator-(P p) const { return P(x - p.x, y - p.y); }
P operator*(T d) const { return P(x * d, y * d); }
P operator/(T d) const { return P(x / d, y / d); }
T dot(P p) const { return x * p.x + y * p.y; }
T cross(P p) const { return x * p.y - y * p.x; }
T cross(P a, P b) const { return (a - *this).cross(b - *this); }
T dist2() const { return x * x + y * y; }
double dist() const { return sqrt((double)dist2()); }
// angle to x-axis in interval [-pi, pi]
double angle() const { return atan2(y, x); }
P unit() const { return *this / dist(); } // makes dist()=1
P perp() const { return P(-y, x); } // rotates +90 degrees
P normal() const { return perp().unit(); }
// returns point rotated 'a' radians ccw around the origin
P rotate(double a) const {
return P(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a));
}
friend ostream& operator<<(ostream& os, P p) {
return os << "(" << p.x << "," << p.y << ")";
}
};
using P = Point<ll>;
vector<P> convexHull(vector<P> pts) {
if (len(pts) <= 1) return pts;
sort(begin(pts), end(pts));
vector<P> h(len(pts) + 1);
int s = 0, t = 0;
for (int it = 2; it--; s = --t, reverse(begin(pts), end(pts)))
for (P p : pts) {
while (t >= s + 2 && h[t - 2].cross(h[t - 1], p) <= 0) t--;
h[t++] = p;
}
return {h.begin(), h.begin() + t - (t == 2 && h[0] == h[1])};
}
void rotate_polygon(vector<P>& poly) {
size_t pos = 0;
for (size_t i = 1; i < poly.size(); i++) {
if (poly[i].y < poly[pos].y ||
(poly[i].y == poly[pos].y && poly[i].x < poly[pos].x))
pos = i;
}
rotate(begin(poly), begin(poly) + pos, end(poly));
}
vector<P> minkowski(vector<P> poly1, vector<P> poly2) {
if (poly1.empty() || poly2.empty()) return {};
rotate_polygon(poly1);
rotate_polygon(poly2);
size_t n = poly1.size(), m = poly2.size();
poly1.push_back(poly1[0]);
poly1.push_back(poly1[1]);
poly2.push_back(poly2[0]);
poly2.push_back(poly2[1]);
vector<P> ret;
size_t i = 0, j = 0;
while (i < n || j < m) {
ret.push_back(poly1[i] + poly2[j]);
auto c = (poly1[i + 1] - poly1[i]).cross(poly2[j + 1] - poly2[j]);
i += c >= 0 && i < n;
j += c <= 0 && j < m;
}
return convexHull(ret);
}
int main() {
std::ios_base::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<vector<P>> candidates(n);
vector<bool> is_leaf(n, false);
vector<vector<int>> graph(n);
for (int i = 0; i < n; i++) {
int k;
cin >> k;
if (k == 0) {
is_leaf[i] = true;
int x, y;
cin >> x >> y;
candidates[i].emplace_back(x, y);
} else {
for (int j = 0; j < k; j++) {
int x;
cin >> x;
graph[i].push_back(--x);
}
}
}
auto neg = [&](const vector<P>& pts) {
vector<P> ret;
for (const auto& p : pts) {
ret.emplace_back(-p.x, -p.y);
}
return ret;
};
auto solve = y_combinator([&](auto self, int curr) -> void {
if (is_leaf[curr]) return;
vector<vector<P>> left, right;
for (const auto& neighbor : graph[curr]) {
self(neighbor);
if (left.empty()) {
left.push_back(neg(candidates[neighbor]));
} else {
left.push_back(minkowski(left.back(), neg(candidates[neighbor])));
}
}
for (int i = len(graph[curr]) - 1; i >= 0; i--) {
auto neighbor = graph[curr][i];
if (right.empty()) {
right.push_back(neg(candidates[neighbor]));
} else {
right.push_back(minkowski(right.back(), neg(candidates[neighbor])));
}
}
reverse(right.begin(), right.end());
for (int i = 0; i < len(graph[curr]); i++) {
vector<P> tmp;
if (i == 0) {
tmp = minkowski(right[i + 1], candidates[graph[curr][i]]);
} else if (i == len(graph[curr]) - 1) {
tmp = minkowski(left[i - 1], candidates[graph[curr][i]]);
} else {
tmp = minkowski(minkowski(left[i - 1], right[i + 1]),
candidates[graph[curr][i]]);
}
candidates[curr].insert(candidates[curr].end(), tmp.begin(), tmp.end());
}
candidates[curr] = convexHull(candidates[curr]);
});
solve(0);
ll ret = 0;
for (const auto& elem : candidates[0]) {
ret = max(ret, elem.dist2());
}
cout << ret << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3856kb
input:
5 4 2 3 4 5 0 2 -2 0 1 3 0 4 -6 0 -18 5
output:
725
result:
ok single line: '725'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3784kb
input:
5 2 2 3 2 4 5 0 1 5 0 -4 -6 0 -1 7
output:
340
result:
ok single line: '340'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3664kb
input:
18 3 4 3 2 2 5 6 3 7 9 8 3 10 11 12 0 4 -1 0 18 49 0 -2 10 2 13 14 0 -5 6 0 5 8 4 15 16 17 18 0 17 3 0 3 -9 0 -7 -1 0 14 -33 0 -23 11 0 11 14 0 2 19
output:
26269
result:
ok single line: '26269'
Test #4:
score: 0
Accepted
time: 171ms
memory: 32100kb
input:
10000 59 2 171 340 509 678 847 1016 1185 1382 1551 1720 1889 2058 2227 2396 2565 2734 2903 3072 3241 3410 3579 3748 3917 4086 4255 4424 4593 4762 4931 5100 5269 5438 5607 5776 5945 6114 6283 6452 6621 6790 6959 7128 7297 7466 7635 7804 7973 8142 8311 8480 8649 8818 8987 9156 9325 9494 9663 9832 2 3 ...
output:
4893524000116
result:
ok single line: '4893524000116'
Test #5:
score: 0
Accepted
time: 179ms
memory: 24792kb
input:
10000 37 2 272 542 812 1082 1352 1622 1892 2162 2432 2702 2972 3242 3512 3782 4052 4322 4592 4862 5132 5402 5672 5942 6212 6482 6752 7022 7292 7571 7841 8111 8381 8651 8921 9191 9461 9731 51 3 8 13 18 23 42 47 52 57 62 67 72 77 82 87 92 97 102 107 112 117 122 127 132 137 142 147 152 157 162 167 172 ...
output:
5186192629829
result:
ok single line: '5186192629829'
Test #6:
score: 0
Accepted
time: 225ms
memory: 47712kb
input:
10000 89 2 114 226 338 450 562 674 786 898 1010 1122 1234 1346 1458 1570 1682 1794 1906 2018 2130 2242 2354 2466 2578 2690 2802 2914 3026 3138 3250 3362 3474 3586 3698 3810 3922 4034 4146 4258 4370 4482 4594 4706 4818 4930 5042 5154 5266 5378 5490 5602 5714 5826 5938 6050 6162 6274 6386 6498 6610 67...
output:
5143217930845
result:
ok single line: '5143217930845'
Test #7:
score: 0
Accepted
time: 1ms
memory: 3784kb
input:
1 0 0 0
output:
0
result:
ok single line: '0'
Test #8:
score: 0
Accepted
time: 1ms
memory: 3604kb
input:
1 0 -1000 0
output:
1000000
result:
ok single line: '1000000'
Test #9:
score: 0
Accepted
time: 1ms
memory: 3564kb
input:
1 0 0 -1000
output:
1000000
result:
ok single line: '1000000'
Test #10:
score: 0
Accepted
time: 1ms
memory: 3612kb
input:
1 0 -1000 1000
output:
2000000
result:
ok single line: '2000000'
Test #11:
score: -100
Runtime Error
input:
2 1 2 0 0 0