Submission #853269

#TimeUsernameProblemLanguageResultExecution timeMemory
853269dlalswp25Circle selection (APIO18_circle_selection)C++17
15 / 100
3025 ms451140 KiB
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int K = 3; int N; int XL[303030]; int XR[303030]; vector<int> U[303030]; vector<int> V[303030]; int ans[303030]; int pu[303030]; struct Circle { int x, y, r, id; } A[303030]; struct DSU { int n; vector<int> l, r; DSU(int _n = 0) : n(_n), l(_n), r(_n) { for (int i = 0; i < n; i++) l[i] = r[i] = i; } int left(int x) { x = min(x, n - 1); if (x < 0 || x == l[x]) return x; return l[x] = left(l[x]); } int right(int x) { x = max(x, 0); if (x >= n || x == r[x]) return x; return r[x] = right(r[x]); } void upd(int x) { l[x] = x - 1; r[x] = x + 1; } }; bool intersect(int i, int j) { int dx = A[i].x - A[j].x, dy = A[i].y - A[j].y, r = A[i].r + A[j].r; return (long long)dx * dx + (long long)dy * dy <= (long long)r * r; } void upd_ans(int cur, int cand) { int &t = ans[cur]; if (A[t].r > A[cand].r || (A[t].r == A[cand].r && t < cand)) return; if (intersect(cur, cand)) t = cand; } struct SegTree { struct Node { vector<pii> v; DSU uf; }; int n, base; vector<Node> T; SegTree(int _n) : n(_n) { for (base = 1; base < n; base <<= 1); T.resize(base + base); } void add_line(int p, int q, int y, int i) { p += base; q += base; p--; q--; while (p <= q) { if (p & 1) { V[i].push_back(T[p].v.size()); T[p].v.emplace_back(y, i); p++; } if (~q & 1) { V[i].push_back(T[q].v.size()); T[q].v.emplace_back(y, i); q--; } p >>= 1; q >>= 1; } } void add_point(int p, int i) { p += base; p--; while (p) { U[i].push_back(T[p].v.size()); p >>= 1; } } void init() { for (int i = 1; i < base + base; i++) T[i].uf = DSU(T[i].v.size()); } void ers_line(int p, int q, int i) { p += base; q += base; p--; q--; int ptr = 0; while (p <= q) { if (p & 1) { T[p].uf.upd(V[i][ptr++]); p++; } if (~q & 1) { T[q].uf.upd(V[i][ptr++]); q--; } p >>= 1; q >>= 1; } } void chk(int p, int i) { p += base; p--; while (p) { int s = U[i][pu[i]++]; int t = s; for (int j = 0; j < K; j++) { t = T[p].uf.right(t); if (t >= T[p].v.size()) break; upd_ans(i, T[p].v[t].second); t++; } t = s; for (int j = 0; j < K; j++) { t = T[p].uf.left(t); if (t < 0) break; upd_ans(i, T[p].v[t].second); t--; } p >>= 1; } } }; int main() { scanf("%d", &N); vector<int> v; for (int i = 1; i <= N; i++) { scanf("%d%d%d", &A[i].x, &A[i].y, &A[i].r); XL[i] = A[i].x - A[i].r; XR[i] = A[i].x + A[i].r; v.push_back(XL[i]); v.push_back(XR[i]); A[i].id = i; } sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); for (int i = 1; i <= N; i++) { XL[i] = lower_bound(v.begin(), v.end(), XL[i]) - v.begin() + 1; XR[i] = lower_bound(v.begin(), v.end(), XR[i]) - v.begin() + 1; } int M = v.size(); SegTree seg(M); sort(A + 1, A + N + 1, [&](Circle &a, Circle &b) { return a.y < b.y; }); for (int i = 1; i <= N; i++) { int j = A[i].id; seg.add_line(XL[j], XR[j], A[i].y, j); seg.add_point(XL[j], j); seg.add_point(XR[j], j); } seg.init(); sort(A + 1, A + N + 1, [&](Circle &a, Circle &b) { return a.id < b.id; }); vector<int> ord(N); iota(ord.begin(), ord.end(), 1); sort(ord.begin(), ord.end(), [&](int a, int b) { if (A[a].r == A[b].r) return a < b; return A[a].r > A[b].r; }); for (int i : ord) { seg.chk(XL[i], i); seg.chk(XR[i], i); if (ans[i] != i) seg.ers_line(XL[i], XR[i], i); } for (int i = 1; i <= N; i++) printf("%d ", ans[i]); puts(""); return 0; }

Compilation message (stderr)

circle_selection.cpp: In member function 'void SegTree::chk(int, int)':
circle_selection.cpp:124:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  124 |     if (t >= T[p].v.size()) break;
      |         ~~^~~~~~~~~~~~~~~~
circle_selection.cpp: In function 'int main()':
circle_selection.cpp:187:2: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  187 |  for (int i = 1; i <= N; i++) printf("%d ", ans[i]); puts("");
      |  ^~~
circle_selection.cpp:187:54: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  187 |  for (int i = 1; i <= N; i++) printf("%d ", ans[i]); puts("");
      |                                                      ^~~~
circle_selection.cpp:141:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |  scanf("%d", &N);
      |  ~~~~~^~~~~~~~~~
circle_selection.cpp:144:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  144 |   scanf("%d%d%d", &A[i].x, &A[i].y, &A[i].r);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...