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;
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[4];
int find_first (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_last (vector <int> &v, int val, int arr[]) {
int l = -1, r = (int) v.size() - 1;
while (l < r) {
int mid = (l + r + 1) / 2;
if (arr[v[mid]] <= val) {
l = mid;
} else {
r = mid - 1;
}
}
return r;
}
int min_last[N_MAX + 2][4];
bool seen[N_MAX + 2][4];
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, 1, 2, 3}) {
if (t == 0 && dir[i] != R && dir[i] != L) {
continue;
}
if (t == 1 && dir[i] != U && dir[i] != D) {
continue;
}
bool positive;
int key;
if (t == 0) {
key = Y[i];
positive = (dir[i] == R);
} else if (t == 1) {
key = X[i];
positive = (dir[i] == U);
} else if (t == 2) {
key = X[i] - Y[i];
positive = (dir[i] == R || dir[i] == U);
} else {
key = X[i] + Y[i];
positive = (dir[i] == R || dir[i] == D);
}
int* arr = (t == 1 ? Y : X);
int coef = (t == 0 || t == 1 ? 1 : 2);
vector <int> &v = V[t][key];
if (t == ti || t == 1) {
if (positive == false) {
int a = find_first(v, arr[i], arr) + 1;
if (a < (int) v.size()) {
consider(v[a], t, min_last[i][ti] + (arr[v[a]] - arr[i]) * coef);
}
} else {
int a = find_last(v, arr[i], arr) - 1;
if (a >= 0) {
consider(v[a], t, min_last[i][ti] + (arr[i] - arr[v[a]]) * coef);
}
}
}
int dist = (min_last[i][ti] + 1) / 2;
if (positive == true) {
int b = find_first(v, arr[i] + dist, arr);
if (b < (int) v.size()) {
consider(v[b], t, (arr[v[b]] - arr[i]) * coef);
}
} else {
int b = find_last(v, arr[i] - dist, arr);
if (b >= 0) {
consider(v[b], t, (arr[i] - arr[v[b]]) * 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[0][Y[i]].push_back(i);
V[1][X[i]].push_back(i);
V[2][X[i] - Y[i]].push_back(i);
V[3][X[i] + Y[i]].push_back(i);
}
for (int i = 1; i <= N; i++) {
for (int t : {0, 1, 2, 3}) {
min_last[i][t] = INT_MAX;
seen[i][t] = false;
}
}
min_last[1][0] = 1; q.push(make_tuple(0, 1, 0));
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++) {
cnt += (seen[i][0] == true || seen[i][1] == true
|| seen[i][2] == true || seen[i][3] == true);
}
V[0].clear(); V[1].clear(); V[2].clear(); V[3].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... |