Submission #243925

#TimeUsernameProblemLanguageResultExecution timeMemory
243925atoizCircle selection (APIO18_circle_selection)C++14
75 / 100
999 ms40184 KiB
// https://oj.uz/submission/77965 #include <iostream> #include <vector> #include <algorithm> #include <cstdio> using namespace std; const double INF = 1e9, EPS = 1e-8; double sqr(double x) { return x * x; } void minimize(double &x, double y) { x = (x < y ? x : y); } void maximize(double &x, double y) { x = (x > y ? x : y); } struct Box { double x0, x1, y0, y1; Box(double _x0 = INF, double _x1 = -INF, double _y0 = INF, double _y1 = -INF): x0(_x0), x1(_x1), y0(_y0), y1(_y1) {} bool intersect(const Box &b) const { return (x0 < b.x1 + EPS && b.x0 < x1 + EPS && y0 < b.y1 + EPS && b.y0 < y1 + EPS); } void expand(const Box &b) { minimize(x0, b.x0), minimize(y0, b.y0), maximize(x1, b.x1), maximize(y1, b.y1); } }; struct Circle { double x, y, r; int i; bool intersect(const Circle &c) const { return sqr(c.x - x) + sqr(c.y - y) < sqr(r + c.r) + EPS; } Box toBox() { return Box(x - r, x + r, y - r, y + r); } }; bool compX(const Circle &a, const Circle &b) { return (abs(a.x - b.x) < EPS ? (a.y < b.y) : (a.x < b.x)); } bool compY(const Circle &a, const Circle &b) { return (abs(a.y - b.y) < EPS ? (a.x < b.x) : (a.y < b.y)); } bool compR(const Circle &a, const Circle &b) { return (abs(a.r - b.r) < EPS ? (a.i < b.i) : (a.r > b.r)); } int n; vector<int> ans; vector<Circle> circles, cirTree; vector<Box> boxTree; void build(int lo = 0, int hi = n - 1, bool byX = 0) { int mid = (lo + hi) >> 1; nth_element(cirTree.begin() + lo, cirTree.begin() + mid, cirTree.begin() + hi + 1, (byX ? compX : compY)); boxTree[mid] = cirTree[mid].toBox(); if (lo < mid) { build(lo, mid - 1, !byX); boxTree[mid].expand(boxTree[(lo + mid - 1) >> 1]); } if (mid < hi) { build(mid + 1, hi, !byX); boxTree[mid].expand(boxTree[(mid + 1 + hi) >> 1]); } // cout << mid << ' ' << lo << ' ' << hi << ' ' << cirTree[mid].i << ": "; // cout << boxTree[mid].x0 << ' ' << boxTree[mid].x1 << ' ' << boxTree[mid].y0 << ' ' << boxTree[mid].y1 << endl; } void get(Circle &c, Box &b, int lo = 0, int hi = n - 1, bool byX = 0) { int mid = (lo + hi) >> 1; if (ans[cirTree[mid].i] == -1 && cirTree[mid].intersect(c)) ans[cirTree[mid].i] = c.i; // cout << c.i << ": " << lo << ' ' << hi << ' ' << cirTree[mid].i << " - "; // cout << boxTree[mid].x0 << ' ' << boxTree[mid].x1 << ' ' << boxTree[mid].y0 << ' ' << boxTree[mid].y1 << endl; boxTree[mid] = Box(INF, -INF, INF, -INF); if (ans[cirTree[mid].i] == -1) boxTree[mid] = cirTree[mid].toBox(); int lc = (lo + mid - 1) >> 1, rc = (mid + 1 + hi) >> 1; if (lo < mid) { if (boxTree[lc].intersect(b)) get(c, b, lo, mid - 1, !byX); boxTree[mid].expand(boxTree[lc]); } if (mid < hi) { if (boxTree[rc].intersect(b)) get(c, b, mid + 1, hi, !byX); boxTree[mid].expand(boxTree[rc]); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; circles.resize(n); for (int i = 0; i < n; ++i) { cin >> circles[i].x >> circles[i].y >> circles[i].r; circles[i].i = i; } sort(circles.begin(), circles.end(), compR); cirTree = circles; boxTree.resize(n); ans.assign(n, -1); build(); for (auto &c : circles) if (ans[c.i] == -1) { ans[c.i] = c.i; Box b = c.toBox(); get(c, b); } for (int i = 0; i < n; ++i) cout << ans[i] + 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...