제출 #1356901

#제출 시각아이디문제언어결과실행 시간메모리
1356901seungchan1eCircle selection (APIO18_circle_selection)C++20
19 / 100
3103 ms291828 KiB
#pragma GCC optimize("O3,Ofast,unroll-loops")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

using ll = long long;

const int MAXN = 303030;

struct chash {
    size_t operator()(const std::pair<int, int>& p) const {
        size_t h1 = std::hash<int>{}(p.first);
        size_t h2 = std::hash<int>{}(p.second);

        return h1 ^ (h2 + 0x9e3779b97f4a7c15ULL + (h1 << 6) + (h1 >> 2));
    }
};

struct Circle {
    int x, y, r, id;
    bool doesIntersect(const Circle& rhs) const {
        ll dx = x - rhs.x;
        ll dy = y - rhs.y;
        ll pr = r + rhs.r;
        return dx * dx + dy * dy <= pr * pr;
    }
};

int floor_div(int a, int b) {
    int q = a / b;
    if((a^b) < 0 && q*b!=a) q--;
    return q;
}

int n, a[MAXN];
Circle cx[MAXN];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(NULL);

    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> cx[i].x >> cx[i].y >> cx[i].r; cx[i].id = i;
    }

    auto rescale = [&](int R) -> gp_hash_table<pair<int, int>, vector<Circle*>, chash> {
        gp_hash_table<pair<int, int>, vector<Circle*>, chash> res;
        for(int i = 1; i <= n; i++) {
            if(a[i]) continue;
            int r = floor_div(cx[i].x, R);
            int c = floor_div(cx[i].y, R);
            res[{r,c}].push_back(&cx[i]);
        }
        return res;
    };

    int R = 1<<30;

    vector<int> v(n);
    iota(v.begin(), v.end(), 1);
    sort(v.begin(), v.end(), [](int i, int j) { return tuple(-cx[i].r, i) < tuple(-cx[j].r, j); });

    auto table = rescale(R);

    for(auto i : v) {
        if(a[i]) continue;
        a[i] = i;

        int oldR = R;
        while(R/2 >= cx[i].r) R /= 2;
        if(oldR != R) table = rescale(R);

        int r = floor_div(cx[i].x, R);
        int c = floor_div(cx[i].y, R);
        for(int dr = -2; dr <= 2; dr++) {
            for(int dc = -2; dc <= 2; dc++) {
                for(auto c : table[{r+dr,c+dc}]) {
                    if(!a[c->id] && cx[i].doesIntersect(*c)) a[c->id] = i;
                }
            }
        }
    }

    for(int i = 1; i <= n; i++) cout << a[i] << " ";
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…