#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
#include <cmath>
#include <unordered_map>
#include <unordered_set>
struct Circle {
int64_t x, y, r, idx;
Circle():
x(0), y(0), r(0), idx(0) {}
Circle(int64_t x, int64_t y, int64_t r, int64_t idx):
x(x), y(y), r(r), idx(idx) {}
bool operator == (const Circle& other) const {
if (this->x!=other.x) return 0;
if (this->y!=other.y) return 0;
if (this->r!=other.r) return 0;
if (this->idx!=other.idx) return 0;
return 1;
}
};
struct CircleHasher {
std::size_t operator() (const Circle& c) const {
return (c.x<<3) ^ (c.y<<5) ^ (c.r>>8) ^ (c.idx<<13);
}
};
int64_t n;
std::vector<Circle> circles;
std::vector<int64_t> eliminator;
int64_t grid_size;
std::unordered_map<int64_t, std::unordered_map<int64_t, std::unordered_set<Circle, CircleHasher>>> grid;
inline int64_t euclid_dist(const Circle& a, const Circle& b) {
return 1LL*(a.x-b.x)*(a.x-b.x) + 1LL*(a.y-b.y)*(a.y-b.y);
}
/*
d(a,b) - a.r <= b.r
sqrt((a.x-b.x)^2 + (a.y-b.y)^2) - a.r <= b.r
sqrt((a.x-b.x)^2 + (a.y-b.y)^2) <= b.r + a.r
(a.x-b.x)^2 + (a.y-b.y)^2 <= (b.r + a.r)^2
*/
inline bool intersect(const Circle& a, const Circle& b) {
return euclid_dist(a,b) <= 1LL*(a.r+b.r)*(a.r+b.r);
}
void init_grid(int64_t size) {
grid.clear();
grid_size = size;
for (int64_t i = 0; i < n; i++) {
if (eliminator[circles[i].idx]) {
continue;
}
grid[circles[i].x/size][circles[i].y/size].insert(circles[i]);
}
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
std::cin >> n;
for (int64_t i = 0, x, y, r; i < n; i++) {
std::cin >> x >> y >> r;
circles.emplace_back(x,y,r,i);
}
std::sort(circles.begin(),circles.end(),[](const Circle& a, const Circle& b) {
return a.r > b.r;
});
eliminator.assign(n, 0);
init_grid(4LL*circles[0].r);
for (const auto& [x, y, r, idx] : circles) {
if (4LL*r < grid_size/2) {
init_grid(4LL*r);
}
if (eliminator[idx]) {
continue;
}
eliminator[idx] = idx+1;
//std::cout << idx << " " << grid_size << "\n";
int64_t grid_x = x / grid_size;
int64_t grid_y = y / grid_size;
for (auto add_x : {-2, -1, 0, 1, 2}) {
for (auto add_y : {-2, -1, 0, 1, 2}) {
for (auto it = grid[grid_x+add_x][grid_y+add_y].begin(); it != grid[grid_x+add_x][grid_y+add_y].end();) {
if (eliminator[it->idx]) {
it = std::next(it);
continue;
}
if (intersect(Circle(x,y,r,idx), *it)) {
eliminator[it->idx] = idx+1;
it = grid[grid_x+add_x][grid_y+add_y].erase(it);
}
else {
it = std::next(it);
}
}
}
}
}
for (int64_t i = 0; i < n; i++) {
std::cout << eliminator[i] << " ";
}
std::cout << "\n";
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |