이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
/** vaziat sorati ghermeze **/
#pragma GCC optimize("O2")
#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 = 1e6 + 10;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const ll inf = 8e18;
const int LOG = 22;
ll pw(ll a , ll b, ll M) { return (!b ? 1 : (b & 1 ? (a * pw(a * a % M, b / 2, M)) % M : pw(a * a % M, b / 2, M))); }
int n, id[N], ord[N], mark[N], Ans[N];
ll X[N], Y[N], R[N];
vector < ll > cm, Vec;
set < pii > 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(); }
bool cross(int i, int j)
{
ll fir = (X[i] - X[j]) * (X[i] - X[j]) + (Y[i] - Y[j]) * (Y[i] - Y[j]);
ll sec = R[i] * R[i] + R[j] * R[j] + 2 * R[i] * R[j];
return sec >= fir;
}
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;
}
sort(ord + 1, ord + n + 1, cmp);
/*for(int i = 1; i <= n; i ++)
{
printf("%d ", ord[i]);
}
printf("\n");*/
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 **/
컴파일 시 표준 에러 (stderr) 메시지
circle_selection.cpp: In function 'int main()':
circle_selection.cpp:71:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
71 | scanf("%d", &n);
| ~~~~~^~~~~~~~~~
circle_selection.cpp:74:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
74 | 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... |