QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#261122 | #6639. Disk Tree | ucup-team1198# | WA | 1ms | 7708kb | C++20 | 6.5kb | 2023-11-22 18:03:09 | 2023-11-22 18:03:11 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define forn(i,n) for (int i = 0; i < int(n); ++i)
#define sz(x) ((int) (x).size())
#define all(x) x.begin(), x.end()
typedef long double ld;
typedef pair<int, int> pii;
using ll = long long;
const int maxn = 200100;
mt19937 rr(111);
ld rndEps() {
return (ld(rr()) / rr.max() - 0.5) * 1e-7;
}
struct pt {
ld x, y, z;
int id;
int pr, nx;
bool inHull;
pt() {}
pt(ld x, ld y, ld z): x(x), y(y), z(z) {}
pt operator-(const pt &p) const {
return pt(x - p.x, y - p.y, z - p.z);
}
ld operator*(const pt &p) const {
return x * p.x + y * p.y + z * p.z;
}
pt operator%(const pt &p) const {
return pt(y * p.z - z * p.y,
z * p.x - x * p.z,
x * p.y - y * p.x);
}
};
ostream &operator<<(ostream &out, pt &p) {
return out << p.x << ' ' << p.y << ' ' << p.z;
}
istream &operator>>(istream &in, pt &p) {
return in >> p.x >> p.y >> p.z;
}
//BEGIN_CODE
typedef tuple<int, int, int> Face;
int n;
pt p[maxn];
namespace Chan {
pt _p[maxn];
ld turny(int p1, int p2, int p3) {
return (p[p2].x - p[p1].x) * (p[p3].y - p[p1].y) -
(p[p3].x - p[p1].x) * (p[p2].y - p[p1].y);
}
//replace y with z
ld turnz(int p1, int p2, int p3) {
return (p[p2].x - p[p1].x) * (p[p3].z - p[p1].z) -
(p[p3].x - p[p1].x) * (p[p2].z - p[p1].z);
}
ld gett(int p1, int p2, int p3) {
if (p1 == -1 || p2 == -1 || p3 == -1) {
return 1e100;
}
ld ty = turny(p1, p2, p3);
if (ty >= 0)
return 1e100;
else
return turnz(p1, p2, p3) / ty;
}
void act(int i) {
if (p[i].inHull) {
p[p[i].nx].pr = p[i].pr;
p[p[i].pr].nx = p[i].nx;
} else {
p[p[i].nx].pr = p[p[i].pr].nx = i;
}
p[i].inHull ^= 1;
}
ld updt(vector<int> &V) {
if (V.empty()) {
return 1e100;
}
int id = V.back();
if (p[id].inHull)
return gett(p[id].pr, p[id].nx, id);
else
return gett(p[id].pr, id, p[id].nx);
}
vector<int> buildHull(int l, int r) {
if (l + 1 >= r) {
p[l].pr = p[l].nx = -1;
p[l].inHull = true;
return {};
}
int mid = (l + r) / 2;
auto L = buildHull(l, mid);
auto R = buildHull(mid, r);
reverse(all(L));
reverse(all(R));
int u = mid - 1, v = mid;
while (true) {
if (p[u].pr != -1 &&
(turny(p[u].pr, u, v) <= 0))
u = p[u].pr;
else if (p[v].nx != -1 &&
(turny(u, v, p[v].nx) <= 0))
v = p[v].nx;
else
break;
}
ld t[6];
t[0] = updt(L);
t[1] = updt(R);
vector<int> A;
while (true) {
t[2] = gett(p[u].pr, v, u);
t[3] = gett(u, p[u].nx, v);
t[4] = gett(u, p[v].pr, v);
t[5] = gett(u, p[v].nx, v);
ld nt = 1e100;
int type = -1;
forn (i, 6)
if (t[i] < nt)
nt = t[i], type = i;
if (nt >= 1e100)
break;
if (type == 0) {
act(L.back());
if (L.back() < u)
A.push_back(L.back());
L.pop_back();
t[0] = updt(L);
} else if (type == 1) {
act(R.back());
if (R.back() > v)
A.push_back(R.back());
R.pop_back();
t[1] = updt(R);
} else if (type == 2) {
A.push_back(u);
u = p[u].pr;
} else if (type == 3) {
A.push_back(u = p[u].nx);
} else if (type == 4) {
A.push_back(v = p[v].pr);
} else if (type == 5) {
A.push_back(v);
v = p[v].nx;
}
}
assert(L.empty() && R.empty());
p[u].nx = v, p[v].pr = u;
for (int i = u + 1; i < v; ++i)
p[i].inHull = false;
for (int i = sz(A) - 1; i >= 0; --i) {
int id = A[i];
if (id <= u || id >= v) {
if (u == id)
u = p[u].pr;
if (v == id)
v = p[v].nx;
act(id);
} else {
p[id].pr = u, p[id].nx = v;
act(id);
if (id >= mid)
v = id;
else
u = id;
}
}
return A;
}
ld dist2d(int i, int j) {
pt p = _p[i] - _p[j];
return hypotl(p.x, p.y);
}
vector<array<int, 2>> getEdges() {
forn (i, n) {
_p[i] = p[i];
p[i].x += rndEps();
p[i].y += rndEps();
p[i].z += rndEps();
p[i].id = i;
}
sort(p, p + n, [](const pt &a, const pt &b) {
return a.x < b.x;
});
auto movie = buildHull(0, n);
int i = 0;
while (!p[i].inHull && i < n)
++i;
assert(i < n);
vector<array<int, 2>> es;
while (i != -1 && p[i].nx != -1) {
int u = p[i].id;
int v = p[p[i].nx].id;
es.push_back({u, v});
i = p[i].nx;
}
for (int x: movie) {
int id = p[x].id;
int pid = p[p[x].pr].id;
int nid = p[p[x].nx].id;
if (!p[x].inHull) {
es.push_back({id, pid});
es.push_back({id, nid});
} else {
es.push_back({pid, nid});
}
act(x);
}
forn (i, n)
p[i] = _p[i];
return es;
}
} //namespace Chan
//END_CODE
const int MAXN = 2e5 + 100;
int dsu_p[MAXN], dsu_sz[MAXN];
int dsu_get(int v) {
return v == dsu_p[v] ? v : dsu_p[v] = dsu_get(dsu_p[v]);
}
bool join(int u, int v) {
u = dsu_get(u); v = dsu_get(v);
if (u == v) return false;
if (dsu_sz[u] < dsu_sz[v]) swap(u, v);;
dsu_sz[u] += dsu_sz[v];
dsu_p[v] = u;
return true;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> n;
vector<array<int, 2>> pt(n);
vector<int> r(n);
for (int i = 0; i < n; ++i) {
cin >> pt[i][0] >> pt[i][1] >> r[i];
p[i].x = pt[i][0];
p[i].y = pt[i][1];
}
auto res = Chan::getEdges();
auto get_len = [&](int i, int j) {
ll dx = (pt[i][0] - pt[j][0]);
ll dy = (pt[i][1] - pt[j][1]);
return dx * dx + dy * dy - 1ll * r[i] * r[i] - 1ll * r[j] * r[j];
};
sort(res.begin(), res.end(), [&](array<int, 2> a, array<int, 2> b) {
return get_len(a[0], a[1]) < get_len(b[0], b[1]);
});
iota(dsu_p, dsu_p + n, 0);
fill(dsu_sz, dsu_sz + n, 1);
cout << "YES\n";
for (auto elem : res) {
if (join(elem[0], elem[1])) {
cout << pt[elem[0]][0] << " " << pt[elem[0]][1] << " ";
cout << pt[elem[1]][0] << " " << pt[elem[1]][1] << "\n";
}
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 5720kb
input:
3 1 0 3 10 10 6 0 5 1
output:
YES 0 5 1 0 0 5 10 10
result:
ok answer = 1
Test #2:
score: 0
Accepted
time: 1ms
memory: 5604kb
input:
2 1 1 1 3 3 1
output:
YES 1 1 3 3
result:
ok answer = 1
Test #3:
score: 0
Accepted
time: 0ms
memory: 7708kb
input:
5 10 10 10 2 0 1 20 20 1 3 20 1 20 0 1
output:
YES 3 20 10 10 10 10 2 0 10 10 20 0 10 10 20 20
result:
ok answer = 1
Test #4:
score: -100
Wrong Answer
time: 0ms
memory: 7592kb
input:
10 29 29 2 28 55 10 99 81 4 17 82 10 45 88 10 48 68 10 0 8 10 98 95 10 34 0 10 17 24 10
output:
YES 29 29 17 24 98 95 99 81 17 24 0 8 45 88 17 82 17 24 34 0 45 88 98 95 17 82 29 29
result:
wrong output format Unexpected end of file - int32 expected