This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/** vaziat sorati ghermeze **/
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define all(x) (x).begin(),(x).end()
#define F first
#define S second
#define Mp make_pair
#define SZ(x) (int)x.size()
#define fast_io ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_io freopen("in.txt" , "r+" , stdin) ; freopen("out.txt" , "w+" , stdout);
const int N = 3e5 + 10;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const ll inf = 8e18;
const int LOG = 22;
int n, id[N], ord[N], Ans[N];
ll X[N], Y[N], R[N], base[N];
vector < ll > cm, Vec;
set < pll > seg[N << 2];
bool cmp(int i, int j) { return R[i] > R[j]; }
inline int lwr(ll x) { return lower_bound(all(cm), x) - cm.begin(); }
inline bool cross(int i, int j)
{
return (base[i] + base[j] + 2 * (X[i] * X[j] + Y[i] * Y[j] + R[i] * R[j])) >= 0;
}
void upd(pii x, int p, int v = 1, int tl = 0, int tr = SZ(cm))
{
if(p > tr || p < tl) return;
seg[v].insert(x);
if(tl == tr) return;
int mid = (tl + tr) >> 1;
upd(x, p, v << 1, tl, mid);
upd(x, p, v << 1 | 1, mid + 1, tr);
}
void get(int l, int r, int v = 1, int tl = 0, int tr = SZ(cm))
{
if(l > tr || r < tl || l > r) return;
if(l <= tl && tr <= r)
{
Vec.push_back(v);
return;
}
int mid = (tl + tr) >> 1;
get(l, r, v << 1, tl, mid);
get(l, r, v << 1 | 1, mid + 1, tr);
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
{
scanf("%lld%lld%lld", &X[i], &Y[i], &R[i]);
cm.push_back(X[i]);
ord[i] = i;
base[i] = R[i] * R[i] - X[i] * X[i] - Y[i] * Y[i];
}
sort(ord + 1, ord + n + 1, cmp);
sort(all(cm));
cm.resize(unique(all(cm)) - cm.begin());
for(int i = 1; i <= n; i ++)
{
id[i] = lwr(X[i]);
upd(Mp(Y[i], i), id[i]);
}
for(int i = 1; i <= n; i ++)
{
int I = ord[i];
if(Ans[I]) continue;
ll l = lwr(X[I] - 2 * R[I]), r = lwr(X[I] + 2 * R[I]), d = Y[I] - 2 * R[I], up = Y[I] + 2 * R[I];
Vec.clear();
get(l, r);
for(auto now : Vec)
{
pii last = Mp(d, -1);
while(1)
{
auto it = seg[now].upper_bound(last);
if(it == seg[now].end()) break;
last = *it;
if(Ans[it->S])
{
seg[now].erase(it);
continue;
}
if(it->F <= up)
{
///printf("checking %d and %d\n", I, it->S);
if(cross(it->S, I))
{
///printf("cross %d and %d\n", I, it->S);
Ans[it->S] = I;
seg[now].erase(it);
}
else
{
continue;
}
}
else
{
break;
}
}
}
}
for(int i = 1; i <= n; i ++)
{
printf("%d ", Ans[i]);
}
return 0;
}
/** test corner cases(n = 1?) watch for overflow or minus indices **/
Compilation message (stderr)
circle_selection.cpp: In function 'int main()':
circle_selection.cpp:67:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
67 | scanf("%d", &n);
| ~~~~~^~~~~~~~~~
circle_selection.cpp:70:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
70 | scanf("%lld%lld%lld", &X[i], &Y[i], &R[i]);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |