Submission #974415

#TimeUsernameProblemLanguageResultExecution timeMemory
974415alextodoranIOI Fever (JOI21_fever)C++17
100 / 100
2340 ms81316 KiB
/** _ _ __ _ _ _ _ _ _ |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) { 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; } } process(1, -1); 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; process(i, t); } 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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...