Submission #974355

#TimeUsernameProblemLanguageResultExecution timeMemory
974355alextodoranIOI Fever (JOI21_fever)C++17
57 / 100
1128 ms42484 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; 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 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...