Submission #895449

#TimeUsernameProblemLanguageResultExecution timeMemory
895449MilosMilutinovicCircle selection (APIO18_circle_selection)C++14
37 / 100
3088 ms860852 KiB
#include <bits/stdc++.h> using namespace std; const int MAX = 3e5; const int N = 4e6; long long x[MAX], y[MAX], r[MAX]; int res[MAX], len, cur; vector<pair<long long, int>> vec[N]; vector<int> xs; vector<int> mn[N]; vector<int> mx[N]; vector<int> fa[N]; vector<bool> rem[N]; void Insert(int i, pair<long long, int> v) { for (int x = i + len; x > 0; x >>= 1) { vec[x].push_back(v); } } void Build() { for (int x = 1; x < 2 * len; x++) { sort(vec[x].begin(), vec[x].end()); int k = (int) vec[x].size(); mn[x] = vector<int>(k); mx[x] = vector<int>(k); fa[x] = vector<int>(k); rem[x] = vector<bool>(k); iota(mn[x].begin(), mn[x].end(), 0); iota(mx[x].begin(), mx[x].end(), 0); iota(fa[x].begin(), fa[x].end(), 0); } } void Unite(int x, int a, int b) { a = fa[x][a]; b = fa[x][b]; if (a == b) { return; } if (mx[x][a] - mn[x][a] > mx[x][b] - mn[x][b]) { swap(a, b); } for (int i = mn[x][a]; i <= mx[x][a]; i++) { fa[x][i] = b; } mx[x][b] = max(mx[x][b], mx[x][a]); mn[x][b] = min(mn[x][b], mn[x][a]); } void Delete(int i, pair<long long, int> v) { for (int x = i + len; x > 0; x >>= 1) { int idx = (int) (lower_bound(vec[x].begin(), vec[x].end(), v) - vec[x].begin()); rem[x][idx] = true; if (idx > 0 && rem[x][idx - 1]) { Unite(x, idx - 1, idx); } if (idx + 1 < (int) vec[x].size() && rem[x][idx + 1]) { Unite(x, idx, idx + 1); } } } void Check(int idx) { if ((x[cur] - x[idx]) * 1LL * (x[cur] - x[idx]) + (y[cur] - y[idx]) * 1LL * (y[cur] - y[idx]) <= (r[cur] + r[idx]) * 1LL * (r[cur] + r[idx])) { res[idx] = cur; Delete((int) (lower_bound(xs.begin(), xs.end(), x[idx]) - xs.begin()), make_pair(y[idx], idx)); } } void Add(int x, long long L, long long R) { int low = 0, high = (int) vec[x].size() - 1, idx = high + 1; while (low <= high) { int mid = low + high >> 1; if (vec[x][mid].first >= L) { idx = mid; high = mid - 1; } else { low = mid + 1; } } //int idx = (int) (lower_bound(vec[x].begin(), vec[x].end(), make_pair(L, -1)) - vec[x].begin()); while (idx < (int) vec[x].size() && vec[x][idx].first <= R) { if (rem[x][idx]) { idx = mx[x][fa[x][idx]] + 1; continue; } Check(vec[x][idx].second); idx += 1; } } void Query(int l, int r, long long L, long long R) { for (l += len, r += len + 1; l < r; l >>= 1, r >>= 1) { if (l & 1) { Add(l++, L, R); } if (r & 1) { Add(--r, L, R); } } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; for (int i = 0; i < n; i++) { cin >> x[i] >> y[i] >> r[i]; } vector<int> order(n); iota(order.begin(), order.end(), 0); sort(order.begin(), order.end(), [&](int i, int j) { if (r[i] != r[j]) { return r[i] > r[j]; } else { return i < j; } }); for (int i = 0; i < n; i++) { xs.push_back(x[i] - 2 * r[i]); xs.push_back(x[i]); xs.push_back(x[i] + 2 * r[i]); } sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end()); int k = (int) xs.size(); len = 1; while (len < k) { len *= 2; } for (int i = 0; i < n; i++) { res[i] = i; int p = (int) (lower_bound(xs.begin(), xs.end(), x[i]) - xs.begin()); Insert(p, make_pair(y[i], i)); } Build(); for (int i : order) { if (res[i] != i) { continue; } cur = i; int p = (int) (lower_bound(xs.begin(), xs.end(), x[i]) - xs.begin()); Delete(p, make_pair(y[i], i)); int L = (int) (lower_bound(xs.begin(), xs.end(), x[i] - 2 * r[i]) - xs.begin()); int R = (int) (lower_bound(xs.begin(), xs.end(), x[i] + 2 * r[i]) - xs.begin()); Query(L, R, y[i] - 2 * r[i], y[i] + 2 * r[i]); } for (int i = 0; i < n; i++) { cout << res[i] + 1 << " "; } return 0; }

Compilation message (stderr)

circle_selection.cpp: In function 'void Add(int, long long int, long long int)':
circle_selection.cpp:76:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   76 |     int mid = low + high >> 1;
      |               ~~~~^~~~~~
#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...