Submission #895427

#TimeUsernameProblemLanguageResultExecution timeMemory
895427MilosMilutinovicCircle selection (APIO18_circle_selection)C++14
37 / 100
3068 ms879036 KiB
#include <bits/stdc++.h> using namespace std; const int N = 4e6; vector<pair<long long, int>> vec[N]; vector<int> qv; vector<int> mn[N]; vector<int> mx[N]; vector<int> fa[N]; vector<bool> rem[N]; void Insert(int x, int l, int r, int i, pair<long long, int> v) { vec[x].push_back(v); if (l == r) { return; } int mid = l + r >> 1; if (i <= mid) { Insert(x << 1, l, mid, i, v); } else { Insert(x << 1 | 1, mid + 1, r, i, v); } } void Build(int x, int l, int r) { 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); if (l == r) { return; } int mid = l + r >> 1; Build(x << 1, l, mid); Build(x << 1 | 1, mid + 1, r); } 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][b]); } void Delete(int x, int l, int r, int i, pair<long long, int> v) { 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); } if (l == r) { return; } int mid = l + r >> 1; if (i <= mid) { Delete(x << 1, l, mid, i, v); } else { Delete(x << 1 | 1, mid + 1, r, i, v); } } void Query(int x, int l, int r, int ll, int rr, long long L, long long R) { if (ll <= l && r <= rr) { 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; } qv.push_back(vec[x][idx].second); idx += 1; } return; } int mid = l + r >> 1; if (rr <= mid) { Query(x << 1, l, mid, ll, rr, L, R); } else if (ll > mid) { Query(x << 1 | 1, mid + 1, r, ll, rr, L, R); } else { Query(x << 1, l, mid, ll, rr, L, R); Query(x << 1 | 1, mid + 1, r, ll, rr, L, R); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<long long> x(n), y(n), r(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; } }); vector<long long> xs; 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(); vector<int> res(n); for (int i = 0; i < n; i++) { res[i] = i; int p = (int) (lower_bound(xs.begin(), xs.end(), x[i]) - xs.begin()); Insert(1, 0, k - 1, p, make_pair(y[i], i)); } Build(1, 0, k - 1); for (int i : order) { if (res[i] != i) { continue; } qv.clear(); int p = (int) (lower_bound(xs.begin(), xs.end(), x[i]) - xs.begin()); Delete(1, 0, k - 1, 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(1, 0, k - 1, L, R, y[i] - 2 * r[i], y[i] + 2 * r[i]); for (int j : qv) { if ((x[i] - x[j]) * 1LL * (x[i] - x[j]) + (y[i] - y[j]) * 1LL * (y[i] - y[j]) <= (r[i] + r[j]) * 1LL * (r[i] + r[j])) { res[j] = i; Delete(1, 0, k - 1, (int) (lower_bound(xs.begin(), xs.end(), x[j]) - xs.begin()), make_pair(y[j], j)); } } } for (int i = 0; i < n; i++) { cout << res[i] + 1 << " "; } return 0; }

Compilation message (stderr)

circle_selection.cpp: In function 'void Insert(int, int, int, int, std::pair<long long int, int>)':
circle_selection.cpp:19:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   19 |   int mid = l + r >> 1;
      |             ~~^~~
circle_selection.cpp: In function 'void Build(int, int, int)':
circle_selection.cpp:40:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   40 |   int mid = l + r >> 1;
      |             ~~^~~
circle_selection.cpp: In function 'void Delete(int, int, int, int, std::pair<long long int, int>)':
circle_selection.cpp:73:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   73 |   int mid = l + r >> 1;
      |             ~~^~~
circle_selection.cpp: In function 'void Query(int, int, int, int, int, long long int, long long int)':
circle_selection.cpp:94:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   94 |   int mid = l + r >> 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...