This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "trilib.h"
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
typedef vector<int> vi;
int q_cnt;
inline bool ccw(int a, int b, int c) {
q_cnt++;
assert(q_cnt <= (int)1e6);
assert(a != b && b != c && a != c);
return !is_clockwise(a, b, c);
}
struct comp {
int k;
comp(int _k) : k(_k) {}
inline bool operator ()(const int &lhs, const int &rhs) const {
if (lhs == k) return true;
if (rhs == k) return false;
return ccw(k, lhs, rhs);
}
};
vi convex_hull(vi pts) {
int n = (int)pts.size();
if (n <= 3) {
/*
printf("convex hull:");
for (auto it : pts) printf(" %d", it);
puts("");
*/
return pts;
}
sort(all(pts), comp(pts[0]));
vi hull;
int sz = 0;
for (int i = 0; i < n; i++) {
while (sz >= 2 && ccw(hull[sz - 2], pts[i], hull[sz - 1])) {
hull.pop_back();
sz--;
}
hull.pb(pts[i]);
sz++;
}
/*
printf("convex hull:");
for (auto it : hull) printf(" %d", it);
puts("");
*/
return hull;
}
#define inc(i, n) ((i + 1) % n)
#define dec(i, n) ((i + n - 1) % n)
int main() {
q_cnt = 0;
int n = get_n();
if (n <= 3) {
give_answer(n);
return 0;
}
vi one, two;
one = {1, 2};
int who = -1;
for (int i = 3; i <= n; i++) {
if (ccw(1, 2, i))
one.pb(i);
else {
if (who == -1)
who = i;
else if (ccw(1, i, who))
who = i;
two.pb(i);
}
}
one = convex_hull(one);
if (two.size() > 1) {
swap(two[0], two[find(all(two), who) - two.begin()]);
}
two = convex_hull(two);
int os = (int)one.size(), ts = (int)two.size();
if (ts == 0) {
give_answer(os);
return 0;
}
// find ccw tangent
int j = 0;
pair<int, int> le(-1, -1), ri(-1, -1);
for (int i = 0; i < os; i++) {
if (ts > 1) {
while (!ccw(one[i], two[j], two[dec(j, ts)]) ||
!ccw(one[i], two[j], two[inc(j, ts)]))
j = inc(j, ts);
}
if (ccw(two[j], one[dec(i, os)], one[i]) && ccw(two[j], one[inc(i, os)], one[i])) {
ri = mp(i, j);
break;
}
}
j = 0;
for (int i = 0; i < os; i++) {
if (ts > 1) {
while (ccw(one[i], two[j], two[dec(j, ts)]) ||
ccw(one[i], two[j], two[inc(j, ts)]))
j = dec(j, ts);
}
if (!ccw(two[j], one[dec(i, os)], one[i]) && !ccw(two[j], one[inc(i, os)], one[i])) {
le = mp(i, j);
break;
}
}
//printf("le: (%d, %d), ri: (%d, %d)\n", le.fi, le.se, ri.fi, ri.se);
int ans = 2;
for (int i = ri.se; i != le.se; i = inc(i, ts))
ans++;
for (int i = le.fi; i != ri.fi; i = inc(i, os))
ans++;
give_answer(ans);
//give_answer((ri.se - le.se + ts) % ts + (le.fi - ri.fi + os) % os);
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |