Submission #974331

#TimeUsernameProblemLanguageResultExecution timeMemory
974331alextodoranIOI Fever (JOI21_fever)C++17
57 / 100
691 ms33192 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[3]; int find_first (vector <int> &v, int x) { int l = 0, r = (int) v.size(); while (l < r) { int mid = (l + r) / 2; if (x <= X[v[mid]]) { r = mid; } else { l = mid + 1; } } return l; } int find_last (vector <int> &v, int x) { int l = -1, r = (int) v.size() - 1; while (l < r) { int mid = (l + r + 1) / 2; if (X[v[mid]] <= x) { l = mid; } else { r = mid - 1; } } return r; } int min_last[N_MAX + 2][3]; bool seen[N_MAX + 2][3]; 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}) { bool positive; int key; if (t == 0) { key = Y[i]; positive = (dir[i] == R); } else if (t == 1) { 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); } vector <int> &v = V[t][key]; int coef = (t == 0 ? 1 : 2); if (t == ti) { if (positive == false) { int a = find_first(v, X[i]) + 1; if (a < (int) v.size()) { consider(v[a], t, min_last[i][ti] + (X[v[a]] - X[i]) * coef); } } else { int a = find_last(v, X[i]) - 1; if (a >= 0) { consider(v[a], t, min_last[i][ti] + (X[i] - X[v[a]]) * coef); } } } if (positive == true) { int b = find_first(v, X[i] + (min_last[i][ti] + 1) / 2); if (b < (int) v.size()) { consider(v[b], t, (X[v[b]] - X[i]) * coef); } } else { int b = find_last(v, X[i] - (min_last[i][ti] + 1) / 2); if (b >= 0) { consider(v[b], t, (X[i] - X[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] - Y[i]].push_back(i); V[2][X[i] + Y[i]].push_back(i); } for (int i = 1; i <= N; i++) { for (int t : {0, 1, 2}) { 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; process(i, t); } int cnt = 0; for (int i = 1; i <= N; i++) { cnt += (seen[i][0] == true || seen[i][1] == true || seen[i][2] == true); } V[0].clear(); V[1].clear(); V[2].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...