QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#261051 | #6639. Disk Tree | ucup-team1198# | ML | 31ms | 242712kb | C++20 | 13.2kb | 2023-11-22 17:38:18 | 2023-11-22 17:38:20 |
Judging History
answer
#include <bits/stdc++.h>
#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()
#define pb push_back
using namespace std;
#define int int64_t
typedef long long ll;
typedef long double ld;
typedef pair<ld, ld> pld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
mt19937 rr(998244353);
void rs(vector<int>& v) {
for (int i = 1; i < sz(v); ++i) {
int j = rr() % (i + 1);
swap(v[i], v[j]);
}
}
struct pt {
ll x, y;
int id;
pt() {}
pt(ll x, ll y, int id = -1) : x(x), y(y), id(id) {}
bool operator<(const pt& other) const {
if (x != other.x) {
return x < other.x;
}
return y < other.y;
}
pt operator-(const pt& other) const {
return {x - other.x, y - other.y};
}
};
ll cross(const pt& p, const pt& q) {
return p.x * q.y - p.y * q.x;
}
ll dot(const pt& p, const pt& q) {
return p.x * q.x + p.y * q.y;
}
struct triangle {
int e[3];
triangle(int a, int b, int c) {
e[0] = a, e[1] = b, e[2] = c;
}
triangle() {}
};
const int nmax = 2e6;
const int emax = nmax * 3;
pii edges[emax];
int g[emax];
triangle triangles[nmax];
vector<pt> p;
int ptre = 0;
int ptr = 0;
int getOther(int v, int a, int b) {
triangle& t = triangles[v];
for (int i = 0; i < 3; ++i) {
int j = t.e[i];
int u = edges[j].first, v = edges[j].second;
if (u != a && u != b) {
return u;
}
if (v != a && v != b) {
return v;
}
}
assert(false);
}
int getId(int v, int a, int b) {
triangle& t = triangles[v];
for (int i = 0; i < 2; ++i) {
int j = t.e[i];
if (edges[j].first + edges[j].second == a + b) {
return j;
}
}
return t.e[2];
}
int getSide(int a, int u, int v) {
assert(a != u && a != v && a >= 0);
if (u >= 0 && v >= 0) {
ll val = cross(p[a] - p[u], p[v] - p[u]);
return (val > 0 ? 1 : (val == 0 ? 0 : -1));
}
if (u == -1 && v == -2) {
return -1;
}
if (u == -2 && v == -1) {
return 1;
}
int ans = (p[a] < p[max(u, v)] ? 1 : -1);
if (u == - 1 || v == -2) {
ans *= (-1);
}
return ans;
}
bool inside(int i, int a, int b = -3, int c = -1) {
if (i < 0) {
return false;
}
if (b == -3) {
int t = a;
int j = triangles[t].e[0];
a = edges[j].first, b = edges[j].second;
c = getOther(t, a, b);
}
int cnt = 0;
if (a < 0) {
++cnt;
}
if (b < 0) {
++cnt;
}
if (c < 0) {
++cnt;
}
int arr[3];
if (cnt >= 2) {
arr[0] = -1, arr[1] = a + b + c + 3, arr[2] = -2;
} else if (cnt == 0) {
arr[0] = a;
if (cross(p[b] - p[a], p[c] - p[a]) < 0) {
arr[1] = b, arr[2] = c;
} else {
arr[1] = c, arr[2] = b;
}
} else if (cnt == 1) {
if (b < 0) {
swap(a, b);
} else if (c < 0) {
swap(a, c);
}
arr[0] = a;
if (a == -1) {
if (p[c] < p[b]) {
arr[1] = b, arr[2] = c;
} else {
arr[1] = c, arr[2] = b;
}
} else {
if (p[b] < p[c]) {
arr[1] = b, arr[2] = c;
} else {
arr[1] = c, arr[2] = b;
}
}
}
for (int j = 0; j < 3; ++j) {
int u = arr[j], v = arr[(j + 1) % 3];
if (u < 0 && v < 0) {
continue;
}
if (u >= 0 && v >= 0) {
if (cross(p[i] - p[u], p[v] - p[u]) < 0) {
return false;
}
} else if (u == -1) {
if (p[v] < p[i]) {
return false;
}
} else if (v == -1) {
if (p[i] < p[u]) {
return false;
}
} else if (u == -2) {
if (p[i] < p[v]) {
return false;
}
} else if (v == -2) {
if (p[u] < p[i]) {
return false;
}
}
}
return true;
}
bool onSegment(int i, int a, int b) {
pt u = p[a] - p[i], v = p[b] - p[i];
return cross(u, v) == 0 && dot(u, v) <= 0;
}
bool onEdge(int i, int id) {
int u = edges[id].first, v = edges[id].second;
if (u >= 0 && v >= 0) {
return onSegment(i, u, v);
}
return false;
}
struct edgeInfo {
int t[2];
int pos[2];
edgeInfo() {
t[0] = t[1] = pos[0] = pos[1] = -1;
}
edgeInfo(int x, int y) {
t[0] = x, pos[0] = y;
t[1] = pos[1] = -1;
}
};
edgeInfo info[emax];
void change(int e, int tOld, int t, int pos) {
if (info[e].t[0] == tOld) {
info[e].t[0] = t;
info[e].pos[0] = pos;
} else {
info[e].t[1] = t;
info[e].pos[1] = pos;
}
}
bool inside(const pt& a, const pt& b, const pt& c, const pt& d) {
pt u1 = a - c, v1 = b - c;
pt u2 = a - d, v2 = b - d;
return ld(abs(cross(u1, v1))) * dot(u2, v2) + ld(abs(cross(u2, v2))) * dot(u1, v1) < 0;
}
queue<int> qu;
int common;
void legalize() {
while (!qu.empty()) {
int id = qu.front();
qu.pop();
if (info[id].t[1] == -1) {
continue;
}
int i, j, k, l;
i = edges[id].first, j = edges[id].second;
int t1 = info[id].t[0], t2 = info[id].t[1];
k = getOther(t1, i, j), l = getOther(t2, i, j);
int a = getId(t1, i, k);
int b = getId(t1, j, k);
int c = getId(t2, i, l);
int d = getId(t2, j, l);
bool flip = false;
if (i < 0 || j < 0) {
if (inside(i, j, k, l) || inside(j, i, k, l)) {
continue;
}
} else {
int sgn1 = getSide(i, k, l), sgn2 = getSide(j, k, l);
if (sgn1 == 0 || sgn2 == 0 || sgn1 == sgn2) {
continue;
}
}
if (i < 0 || j < 0 || k < 0 || l < 0) {
if (min(i, j) < min(k, l)) {
flip = true;
}
} else {
if (inside(p[i], p[j], p[k], p[l])) {
flip = true;
}
}
if (flip) {
edges[ptre++] = {k, l};
triangles[ptr++] = {ptre - 1, a, c};
change(a, t1, ptr - 1, 1);
change(c, t2, ptr - 1, 2);
change(ptre - 1, -1, ptr - 1, 0);
triangles[ptr++] = {ptre - 1, b, d};
change(b, t1, ptr - 1, 1);
change(d, t2 , ptr - 1, 2);
change(ptre - 1, -1, ptr - 1, 0);
g[t1 * 3] = ptr - 2;
g[t1 * 3 + 1] = ptr - 1;
g[t2 * 3] = ptr - 2;
g[t2 * 3 + 1] = ptr - 1;
if (common == k) {
qu.push(c);
qu.push(d);
} else {
qu.push(a);
qu.push(b);
}
}
}
}
ll dist2(const pt& a, const pt& b) {
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
struct edge {
int u, v;
ll cost;
bool operator<(const edge& other) const {
return cost < other.cost;
}
};
vector<int> parent;
vector<int> ssize;
vector<vector<int> > subtree;
vector<vector<int> > w;
vector<pii> zapr;
vector<array<int, 2>> solve(vector<array<int, 2>> pt_) {
int n = pt_.size();
memset(g, -1, sizeof(g));
ptr = 0;
ptre = 0;
p.resize(n);
vector<int> newId(n);
for (int i = 0; i < n; ++i) {
p[i].x = pt_[i][0];
p[i].y = pt_[i][1];
p[i].id = i;
}
sort(all(p));
reverse(all(p));
for (int i = 0; i < n; ++i) {
newId[p[i].id] = i;
}
edges[ptre++] = {-1, 0};
edges[ptre++] = {0, -2};
edges[ptre++] = {-2, -1};
triangles[ptr++] = {0, 1, 2};
info[0] = {0, 0};
info[1] = {0, 1};
info[2] = {0, 2};
vector<int> perm;
for (int i = 1; i < n; ++i) {
perm.pb(i);
}
rs(perm);
for (int i = 0; i < sz(perm); ++i) {
int v = 0;
while (g[v * 3] != -1) {
if (g[v * 3 + 2] == -1) {
int id = g[v * 3];
int j = triangles[id].e[0];
int a = edges[j].first, b = edges[j].second;
int c = getOther(id, a, b);
int sgn1 = getSide(perm[i], a, b);
int sgn2 = getSide(c, a, b);
if (sgn1 == 0 || sgn1 == sgn2) {
v = id;
} else {
v = g[v * 3 + 1];
}
} else {
bool done = false;
for (int z = 0; z + 1 < 3; ++z) {
int to = g[v * 3 + z];
if (inside(perm[i], to)) {
done = true;
v = to;
break;
}
}
if (!done) {
v = g[v * 3 + 2];
}
}
}
int on = -1;
for (int z = 0; z < 3; ++z) {
int j = triangles[v].e[z];
if (onEdge(perm[i], j)) {
on = j;
break;
}
}
if (on == -1) {
int j = triangles[v].e[0];
int a, b, c;
a = edges[j].first, b = edges[j].second;
c = getOther(v, a, b);
edges[ptre++] = {perm[i], a};
edges[ptre++] = {perm[i], b};
edges[ptre++] = {perm[i], c};
int k = ptre;
triangles[ptr++] = {triangles[v].e[0], k - 2, k - 3};
change(k - 2, -1, ptr - 1, 1);
change(k - 3, -1, ptr - 1, 2);
change(triangles[v].e[0], v, ptr - 1, 0);
triangles[ptr++] = {getId(v, b, c), k - 1, k - 2};
change(k - 1, -1, ptr - 1, 1);
change(k - 2, -1, ptr - 1, 2);
change(getId(v, b, c), v, ptr - 1, 0);
triangles[ptr++] = {getId(v, c, a), k - 3, k - 1};
change(k - 3, -1, ptr - 1, 1);
change(k - 1, -1, ptr - 1, 2);
change(getId(v, c, a), v, ptr - 1, 0);
g[v * 3] = ptr - 1;
g[v * 3 + 1] = ptr - 2;
g[v * 3 + 2] = ptr - 3;
for (int z = 0; z < 3; ++z) {
qu.push(triangles[v].e[z]);
}
} else {
int a = edges[on].first, b = edges[on].second;
int u = info[on].t[1] + info[on].t[0] - v;
int c = getOther(v, a, b);
int d = getOther(u, a, b);
edges[ptre++] = {perm[i], a};
edges[ptre++] = {perm[i], b};
edges[ptre++] = {perm[i], c};
edges[ptre++] = {perm[i], d};
int k = ptre;
vector<int> vctx = {v, u};
vector<int> vctz = {c, d};
vector<int> vct = {a, b};
for (int j = 0; j < 2; ++j) {
int x = vctx[j];
int z = vctz[j];
for (int q = 0; q < 2; ++q) {
int id = getId(x, vct[q], z);
triangles[ptr++] = {k - 2 + j, k - 4 + q, id};
g[x * 3 + q] = ptr - 1;
change(id, x, ptr - 1, 2);
change(k - 4 + q, -1, ptr - 1, 1);
change(k - 2 + j, -1, ptr - 1, 0);
}
}
qu.push(getId(v, a, c));
qu.push(getId(v, c, b));
qu.push(getId(u, a, d));
qu.push(getId(u, b, d));
}
common = perm[i];
legalize();
}
vector<array<int, 2>> ee;
for (int v = 0; v < ptr; ++v) {
if (g[v * 3] != -1) {
continue;
}
for (int z = 0; z < 3; ++z) {
int j = triangles[v].e[z];
int u = edges[j].first, v = edges[j].second;
if (u < 0 || v < 0) {
continue;
}
ee.pb({p[u].id, p[v].id});
}
}
return ee;
}
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);
int n;
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];
}
auto res = solve(pt);
auto get_len = [&](int i, int j) {
int dx = (pt[i][0] - pt[j][0]);
int dy = (pt[i][1] - pt[j][1]);
return dx * dx + dy * dy - r[i] * r[i] - 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: 15ms
memory: 238732kb
input:
3 1 0 3 10 10 6 0 5 1
output:
YES 1 0 0 5 0 5 10 10
result:
ok answer = 1
Test #2:
score: 0
Accepted
time: 12ms
memory: 240872kb
input:
2 1 1 1 3 3 1
output:
YES 1 1 3 3
result:
ok answer = 1
Test #3:
score: 0
Accepted
time: 19ms
memory: 238820kb
input:
5 10 10 10 2 0 1 20 20 1 3 20 1 20 0 1
output:
YES 3 20 10 10 2 0 10 10 10 10 20 20 20 0 10 10
result:
ok answer = 1
Test #4:
score: 0
Accepted
time: 4ms
memory: 238768kb
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 17 24 29 29 98 95 99 81 48 68 45 88 17 24 0 8 48 68 28 55 28 55 29 29 45 88 17 82 34 0 17 24 48 68 99 81
result:
ok answer = 1
Test #5:
score: 0
Accepted
time: 4ms
memory: 240876kb
input:
100 490 783 12 666 460 55 561 245 6 223 323 25 3 520 77 225 161 24 514 190 16 997 914 100 412 265 100 374 610 36 296 854 39 601 901 2 307 21 100 390 422 24 940 414 32 332 438 35 553 992 100 235 775 3 656 901 37 770 417 22 649 305 100 448 84 3 375 939 77 910 847 9 776 357 37 743 97 100 371 502 39 508...
output:
YES 770 417 749 401 809 794 811 693 255 263 267 249 448 84 447 40 95 208 76 226 255 263 195 241 951 132 975 153 412 265 422 163 833 250 837 286 137 156 133 115 601 901 553 992 899 204 964 284 32 773 81 790 563 635 533 734 787 237 833 250 160 703 235 775 448 84 482 132 769 474 846 495 865 52 897 76 9...
result:
ok answer = 1
Test #6:
score: 0
Accepted
time: 8ms
memory: 238824kb
input:
200 2948 9798 687 3897 647 35 3918 587 28 1262 2717 206 1315 9524 20 2381 305 1000 4344 6858 20 6234 8949 53 5168 4772 85 5044 6109 158 72 7670 132 7300 1213 837 5427 2263 1000 1785 3009 276 6136 1421 43 1629 5620 29 6445 9489 242 8443 3141 1000 4118 4307 63 1874 5238 291 1964 5785 73 7794 3934 18 3...
output:
YES 8808 4438 9278 4357 3897 647 3918 587 6125 9979 6062 9827 9598 2086 9940 2103 9881 5238 9965 5083 1756 8604 2704 8279 4946 6252 5044 6109 3427 769 3524 778 9434 2844 9514 2928 2981 8806 2975 8690 3881 5104 3074 4508 7018 8858 7259 8795 4344 6858 4160 6939 8791 6984 8868 7083 3731 790 3524 778 61...
result:
ok answer = 1
Test #7:
score: 0
Accepted
time: 23ms
memory: 238856kb
input:
300 42942 37079 222 49441 21821 1695 61023 31153 561 86630 26307 352 36940 78253 213 7841 81086 626 47425 22290 374 17694 68695 648 38259 64794 998 43599 46942 9662 9204 2816 1965 38652 83568 4057 4046 29001 1034 72591 63214 587 75984 64859 1112 70005 72177 576 34522 52126 652 56627 48785 1747 78820...
output:
YES 97653 50419 97975 50437 66345 83699 65601 83613 60208 7681 59945 7276 48642 86091 49759 86207 38589 38309 39086 38101 77511 65089 77469 64494 888 90680 649 91204 27731 53830 26217 53454 26217 53454 26810 54901 73117 73768 73572 71685 80020 86672 81812 87290 83090 83694 80629 84138 10530 82824 11...
result:
ok answer = 1
Test #8:
score: 0
Accepted
time: 8ms
memory: 239028kb
input:
1000 558504245 246224785 100000000 971981730 913036757 1821458 198791767 482624549 5998171 540520619 353988177 8924682 183178222 46223569 9859905 118485076 22129062 7497235 274928891 417171180 372954 230079763 468235825 289869 859092765 562864738 5551376 129036518 743777318 3969979 265158223 3092933...
output:
YES 741963125 249632478 749654230 245631243 299731657 172180704 299412197 169909676 744268608 502811255 749780007 500202962 719129758 362901109 718859247 362033902 637773206 344877200 637256234 344115816 506923531 47961807 496800989 56076643 802986231 620294429 801971917 620730756 781123049 61470226...
result:
ok answer = 1
Test #9:
score: 0
Accepted
time: 15ms
memory: 241580kb
input:
3000 442876143 334276354 3627270 526253918 947313397 2498956 566692880 229330019 4243066 497859604 658736917 13012787 315969653 65582717 1400013 394215653 932651144 1655676 58249045 973232518 860150 860773683 959388251 1594726 23803673 921365885 5926749 730359196 818999592 1521282 971839312 22835235...
output:
YES 390223036 962557192 395065091 961684986 278141533 211881820 279342544 211481944 403421973 160674394 388540598 156256536 20056939 793312760 23989584 790455936 370084895 524700222 370053752 526851391 83605887 493352547 174473105 535104153 264607878 236174923 264565844 235783795 799403583 515048991...
result:
ok answer = 1
Test #10:
score: 0
Accepted
time: 27ms
memory: 241852kb
input:
7000 601805179 978984160 464352 918208048 607538668 2214109 328147216 806677103 3901695 961794394 719893281 1114470 453816635 992288784 274949 778724702 692479905 1170018 169287513 886715521 576156 812072299 118324465 93778 726229729 150105801 3593039 368683874 642143790 1277375 40087476 151799345 4...
output:
YES 147132881 538273755 124294320 540614604 382625944 278906969 382515546 278713564 697337247 794958320 696633780 793111357 992855761 910338438 987588473 906458142 704574232 313018143 704454970 314676892 564617520 977122934 560644939 974602541 15064352 99341679 13828463 98607732 669134218 735724279 ...
result:
ok answer = 1
Test #11:
score: 0
Accepted
time: 31ms
memory: 242712kb
input:
10000 645 4710 5 1554 4072 7 6505 2760 1 6125 8212 11 9802 9537 3 6584 4356 6 1104 6649 23 4580 2623 20 3107 2460 1 4689 1662 2 7815 161 14 8718 3658 28 2900 63 15 1741 7296 44 8380 4608 50 2212 8514 4 7919 3069 17 1638 6057 3 504 9867 18 7869 8021 14 866 9239 5 3452 8042 4 9049 7222 4 4447 1004 5 9...
output:
YES 5031 7923 5034 7922 6548 2638 6545 2639 9183 8362 9182 8365 1872 6231 1873 6228 2420 5385 2423 5386 5944 3595 5945 3599 2936 3267 2937 3263 6972 4187 6971 4183 2542 2107 2542 2110 4845 6849 4847 6846 2028 8861 2031 8864 4626 3789 4628 3786 8 141 9 136 4404 4604 4399 4603 970 9908 972 9912 2416 9...
result:
ok answer = 1
Test #12:
score: -100
Memory Limit Exceeded
input:
100000 956095525 596102106 2 461544095 587257542 118 884402350 357055086 14228 547768407 186052059 263162 827807425 303694996 474924 692537425 44608243 131609 504660936 451030143 15134 207539367 899608364 20283 919236289 724317925 6 386476373 727023405 323 781914406 792770865 1064 411548762 2476126 ...
output:
YES 737182558 31629185 737205369 31606130 892696561 422861520 892145544 423239295 430638901 427457801 430648820 427446762 744488111 310224678 744495274 310246137 468728091 140185254 468718121 140164034 685322409 737069869 685305440 737074349 801637807 582451012 801681587 582450259 790259785 35554795...