제출 #1258889

#제출 시각아이디문제언어결과실행 시간메모리
1258889sunflowerCircle selection (APIO18_circle_selection)C++17
19 / 100
345 ms29640 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define MASK(x) (1LL << (x)) #define BIT(x, i) (((x) >> (i)) & 1) #define SZ(x) ((int) (x).size()) #define ALL(a) (a).begin(), (a).end() #define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i) #define FORD(i, a, b) for (int i = (a), _b = (b); i >= _b; --i) #define REP(i, n) for (int i = 0, _n = (n); i < _n; ++i) #define debug(x) cout << #x << " = " << (x) << endl; #define fi first #define se second #define left __left #define right __right #define prev __prev #define next __next template <class X, class Y> bool maximize(X &x, Y y) { if (x < y) return x = y, true; else return false; } template <class X, class Y> bool minimize(X &x, Y y) { if (x > y) return x = y, true; else return false; } template <class T> void remove_dup(T &v) { sort(ALL(v)); v.resize(unique(ALL(v)) - v.begin()); } int POS(int x, const vector <int> &v) { return lower_bound(v.begin(), v.end(), x) - v.begin() + 1; } const int inf = (int) 1e9 + 7; #define MAX_N 300'300 int n; int del[MAX_N + 2]; struct Circle { int x, y, r, id; bool operator < (const Circle &other) const { if (r != other.r) return (r > other.r); return (id < other.id); } friend istream& operator >> (istream &in, Circle &c) { in >> c.x >> c.y >> c.r; return in; } } cir[MAX_N + 2]; ll sqr(ll x) { return 1LL * x * x; } namespace subtask1 { bool check() { return (n <= 5000); } void solve() { sort(cir + 1, cir + 1 + n); memset(del, 0, sizeof(del)); FOR(i, 1, n) { int curID = cir[i].id; if (del[curID]) continue; del[curID] = curID; FOR(j, i + 1, n) { if (del[cir[j].id]) continue; if (sqr(cir[i].x - cir[j].x) + sqr(cir[i].y - cir[j].y) <= sqr(cir[i].r + cir[j].r)) { del[cir[j].id] = curID; } } } FOR(i, 1, n) cout << del[i] << " "; } }; const int TREE_SIZE = MAX_N * 2; struct Segtree { int seg[TREE_SIZE * 4 + 2], lazy[TREE_SIZE * 4 + 2]; int n; void initTree(int _n) { n = _n; FOR(i, 0, 4 * _n + 7) { seg[i] = inf; lazy[i] = inf; } } void down(int id, int l, int r) { if (lazy[id] == inf || l >= r) return; int &v = lazy[id]; FOR(j, 2 * id, 2 * id + 1) { minimize(seg[j], v); minimize(lazy[j], v); } v = inf; } void update(int id, int l, int r, int u, int v, int val) { if (l > v || u > r) return; if (u <= l && r <= v) { minimize(seg[id], val); minimize(lazy[id], val); return; } down(id, l, r); int g = (l + r) >> 1; update(id << 1, l, g, u, v, val); update(id << 1 | 1, g + 1, r, u, v, val); seg[id] = min(seg[id << 1], seg[id << 1 | 1]); } int get(int id, int l, int r, int u, int v) { if (l > v || u > r) return inf; if (u <= l && r <= v) return seg[id]; down(id, l, r); int g = (l + r) >> 1; return min(get(id << 1, l, g, u, v), get(id << 1 | 1, g + 1, r, u, v)); } void update(int u, int v, int val) { update(1, 1, n, u, v, val); } int get(int u, int v) { if (u > v) return inf; return get(1, 1, n, u, v); } } st; namespace subtask2 { bool check() { FOR(i, 1, n) if (cir[i].y != 0) return false; return true; } void solve() { sort(cir + 1, cir + 1 + n); vector <int> compressed; FOR(i, 1, n) { compressed.push_back(cir[i].x - cir[i].r); compressed.push_back(cir[i].x + cir[i].r); } remove_dup(compressed); int lim = SZ(compressed) + 2; st.initTree(lim); memset(del, 0, sizeof(del)); FOR(i, 1, n) { int curID = cir[i].id; int L = POS(cir[i].x - cir[i].r, compressed), R = POS(cir[i].x + cir[i].r, compressed); int get_val = st.get(L, R); if (get_val != inf) del[curID] = cir[get_val].id; else { // assert(get_val == inf); del[curID] = curID; st.update(L, R, i); } } FOR(i, 1, n) cout << del[i] << " "; } }; const int dx[] = {-2, -1, 0, 1, 2}; const int dy[] = {-2, -1, 0, 1, 2}; namespace subtask3 { bool check() { FOR(i, 2, n) if (cir[i].r != cir[1].r) return false; return true; } // ko can xoa vi tong lan duyet ko qua lon /// sum visit all circle <= 50 * n; pair <int, int> nen[MAX_N + 2]; struct Data { pair <int, int> dir; int id; bool operator < (const Data &other) const { if (dir != other.dir) return (dir < other.dir); return (id < other.id); } }; void solve() { /// compressed into board with each cell have size R x R; FOR(i, 1, n) nen[i] = {cir[i].x / cir[i].r, cir[i].y / cir[i].r}; vector <Data> v; FOR(i, 1, n) v.push_back({nen[i], i}); sort(ALL(v)); FOR(i, 1, n) { if (del[i]) continue; /// kc toi da de 2 o giao nhau; FOR(nx, nen[i].fi -2, nen[i].fi + 2) FOR(ny, nen[i].se -2, nen[i].se + 2) { pair <int, int> curDir = {nx, ny}; int l = 0, r = SZ(v) - 1, g, pos = -1; while (l <= r) { g = (l + r) >> 1; if (v[pos].dir < curDir) l = g + 1; else pos = g, r = g - 1; } if (pos == -1) continue; while (pos < SZ(v)) { pair <int, int> tmp = v[pos].dir; if (tmp != curDir) break; int id = v[pos].id; if (!del[id] && sqr(cir[i].x - cir[id].x) + sqr(cir[i].y - cir[id].y) <= sqr(cir[i].r + cir[id].r)) { del[id] = i; } ++pos; } } } FOR(i, 1, n) cout << del[i] << " "; } }; namespace subtask4 { void solve() { sort(cir + 1, cir + 1 + n); } }; int main() { ios_base::sync_with_stdio(false);cin.tie(nullptr); cin >> n; FOR(i, 1, n) cin >> cir[i], cir[i].id = i; if (subtask1 :: check()) return subtask1 :: solve(), 0; if (subtask2 :: check()) return subtask2 :: solve(), 0; if (subtask3 :: check()) return subtask3 :: solve(), 0; assert(false); return 0; }
#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...