This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/**
_ _ __ _ _ _ _ _ _
|a ||t ||o d | |o |
| __ _| | _ | __| _ |
| __ |/_ | __ /__\ / _\|
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N_MAX = 100000;
const int U = 0, R = 1, D = 2, L = 3;
const int RU = 4, RD = 5, LD = 6, LU = 7;
int N;
int X[N_MAX + 2], Y[N_MAX + 2];
int order[N_MAX + 2];
int dir[N_MAX + 2];
void get_dir () {
dir[1] = R;
for (int i = 2; i <= N; i++) {
if (abs(X[i] - X[1]) > abs(Y[i] - Y[1])) {
dir[i] = (X[i] < X[1] ? R : L);
} else if (abs(Y[i] - Y[1]) > abs(X[i] - X[1])) {
dir[i] = (Y[i] < Y[1] ? U : D);
} else {
if (X[i] < X[1]) {
dir[i] = R;
} else {
dir[i] = (Y[i] < Y[1] ? U : D);
}
}
}
}
unordered_map <int, vector <int>> V[8];
int find_higher (vector <int> &v, int val, int arr[]) {
int l = 0, r = (int) v.size();
while (l < r) {
int mid = (l + r) / 2;
if (val <= arr[v[mid]]) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
int find_lower (vector <int> &v, int val, int arr[]) {
int l = 0, r = (int) v.size();
while (l < r) {
int mid = (l + r) / 2;
if (arr[v[mid]] <= val) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
int min_last[N_MAX + 2][8];
bool seen[N_MAX + 2][8];
priority_queue <tuple <int, int, int>> q;
void consider (int i, int t, int last) {
if (last < min_last[i][t]) {
min_last[i][t] = last;
q.push(make_tuple(-last, i, t));
}
}
void process (int i, int ti) {
for (int t = 0; t < 8; t++) {
int key;
bool positive;
bool go;
if (t < 4) {
go = (dir[i] == t);
key = (t % 2 == 0 ? X[i] : Y[i]);
positive = (t < 2);
} else {
go = (dir[i] == t - 4 || dir[i] == (t - 4 + 1) % 4);
key = (t % 2 == 0 ? X[i] - Y[i] : X[i] + Y[i]);
positive = (t < 6);
}
int *arr = (t == 0 || t == 2 ? Y : X);
int coef = (t < 4 ? 1 : 2);
vector <int> &v = V[t][key];
if (t == ti && i != 1) {
int a;
if (positive == true) {
a = find_higher(v, arr[i], arr) + 1;
} else {
a = find_lower(v, arr[i], arr) + 1;
}
if (a < (int) v.size()) {
consider(v[a], t, min_last[i][ti] + abs(arr[v[a]] - arr[i]) * coef);
}
}
if (go == false) {
continue;
}
int dist = (coef == 2 ? (min_last[i][ti] + 1) / 2 : min_last[i][ti]);
int b;
if (positive == true) {
b = find_higher(v, arr[i] + dist, arr);
} else {
b = find_lower(v, arr[i] - dist, arr);
}
if (b < (int) v.size()) {
consider(v[b], t, abs(arr[v[b]] - arr[i]) * coef);
}
}
}
int solve () {
get_dir();
iota(order + 1, order + N + 1, 1);
sort(order + 1, order + N + 1, [&] (const int &i, const int &j) {
return make_pair(X[i], Y[i]) < make_pair(X[j], Y[j]);
});
for (int k = 1; k <= N; k++) {
int i = order[k];
V[U][X[i]].push_back(i);
V[R][Y[i]].push_back(i);
V[RU][X[i] - Y[i]].push_back(i);
V[RD][X[i] + Y[i]].push_back(i);
}
for (int k = N; k >= 1; k--) {
int i = order[k];
V[D][X[i]].push_back(i);
V[L][Y[i]].push_back(i);
V[LD][X[i] - Y[i]].push_back(i);
V[LU][X[i] + Y[i]].push_back(i);
}
for (int i = 1; i <= N; i++) {
for (int t = 0; t < 8; t++) {
min_last[i][t] = INT_MAX;
seen[i][t] = false;
}
}
for (int t = 0; t < 8; t++) {
min_last[1][t] = 1; q.push(make_tuple(0, 1, t));
}
while (q.empty() == false) {
int i = get <1> (q.top()), t = get <2> (q.top());
q.pop();
if (seen[i][t] == true) {
continue;
}
seen[i][t] = true;
// cout << "min_last[" << i << "][" << t << "] = " << min_last[i][t] << "\n";
process(i, t);
}
// cout << "\n";
int cnt = 0;
for (int i = 1; i <= N; i++) {
for (int t = 0; t < 8; t++) {
if (seen[i][t] == true) {
cnt++;
break;
}
}
}
for (int t = 0; t < 8; t++) {
V[t].clear();
}
return cnt;
}
void rot90 () {
for (int i = 1; i <= N; i++) {
swap(X[i], Y[i]); X[i] = -X[i];
}
}
int main () {
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> N;
for (int i = 1; i <= N; i++) {
cin >> X[i] >> Y[i];
}
int answer = solve();
rot90(); answer = max(answer, solve());
rot90(); answer = max(answer, solve());
rot90(); answer = max(answer, solve());
cout << answer << "\n";
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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |