QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#557088 | #6403. Master of Polygon | pandapythoner | WA | 652ms | 22664kb | C++23 | 6.6kb | 2024-09-11 02:49:59 | 2024-09-11 02:49:59 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define len(a) int((a).size())
#define all(a) begin(a), end(a)
#define rep(i, n) for (int i = 0; i < (n); i++)
mt19937 rnd(234234);
ld pi = atan2l(0, -1);
double eps = 1e-7;
struct vec {
ll x, y;
vec() {}
vec(ll x, ll y) : x(x), y(y) {}
};
vec operator+(const vec& a, const vec& b) {
return vec{ a.x + b.x, a.y + b.y };
}
vec operator-(const vec& a, const vec& b) {
return vec{ a.x - b.x, a.y - b.y };
}
ll operator*(const vec& a, const vec& b) {
return a.x * b.x + a.y * b.y;
}
ll operator%(const vec& a, const vec& b) {
return a.x * b.y - a.y * b.x;
}
ll sign(ll x) {
if (x > 0) return 1;
if (x < 0) return -1;
return 0;
}
bool intersects(const vec& a, const vec& b, const vec& c, const vec& d) {
if ((a - b) % (c - d) == 0) {
if ((c - a) % (d - a) != 0) return false;
if (max(a.x, b.x) < min(c.x, d.x) or max(c.x, d.x) < min(a.x, b.x)) return false;
if (max(a.y, b.y) < min(c.y, d.y) or max(c.y, d.y) < min(a.y, b.y)) return false;
return true;
}
if (sign((b - a) % (c - a)) * sign((b - a) % (d - a)) > 0) return false;
if (sign((d - c) % (a - c)) * sign((d - c) % (b - c)) > 0) return false;
return true;
}
int n, q;
vector<vec> poly;
vector<pair<vec, vec>> tests;
vector<int> result;
void solve_slow() {
result.resize(q);
rep(i, q) {
auto& [a, b] = tests[i];
result[i] = false;
rep(j, n) {
auto& c = poly[j];
auto& d = poly[j == n - 1 ? 0 : j + 1];
if (intersects(a, b, c, d)) {
result[i] = true;
break;
}
}
}
}
double get(const vec& a, const vec& b, ll x) {
if (a.x == b.x) return a.y;
return a.y + (double(x - a.x)) / (b.x - a.x) * (b.y - a.y);
}
vector<int> sift_ind(vector<int> ind) {
vector<int> result;
}
vector<pair<vec, vec>> pull_lines(const vector<vector<vec>>& curves, ll xl, ll xr) {
vector<pair<vec, vec>> result;
for (auto& curve : curves) {
for (int i = 0; i + 1 < len(curve); i += 1) {
vec a = curve[i], b = curve[i + 1];
if (a.x > b.x) swap(a, b);
if (a.x <= xl and b.x >= xr) {
result.push_back(make_pair(a, b));
}
}
}
return result;
}
vector<vector<vec>> cut_curves(const vector<vector<vec>>& curves, ll xl, ll xr) {
vector<vector<vec>> result;
for (auto& curve : curves) {
for (int l = 0; l < len(curve); l += 1) {
if (curve[l].x < xl or curve[l].x > xr) continue;
int r = l;
while (r + 1 < len(curve) and (xl <= curve[r + 1].x and curve[r + 1].x <= xr)) {
r += 1;
}
int nl = max(0, l - 1);
int nr = min(r + 1, len(curve) - 1);
result.push_back(vector<vec>(curve.begin() + nl, curve.begin() + nr + 1));
l = r;
}
}
return result;
}
void solve_rec(vector<vector<vec>> curves, vector<int> ind, ll xl, ll xr) {
vector<int> new_ind;
for (auto i : ind) {
if (!result[i] and tests[i].second.x >= xl and tests[i].first.x <= xr) new_ind.push_back(i);
}
ind = new_ind;
if (curves.empty() or ind.empty()) {
return;
}
new_ind.clear();
auto lines = pull_lines(curves, xl, xr);
curves = cut_curves(curves, xl, xr);
sort(all(lines), [&](const pair<vec, vec>& a, const pair<vec, vec>& b) {
return get(a.first, a.second, xl) + eps < get(b.first, b.second, xl);
});
auto get_pos = [&](const vec& a) {
int tl = -1;
int tr = len(lines);
while (tl + 1 < tr) {
int tm = (tl + tr) / 2;
auto& [c, d] = lines[tm];
if ((d - c) % (a - c) > 0) {
tl = tm;
} else {
tr = tm;
}
}
return tl;
};
if (!lines.empty()) {
for (auto i : ind) {
auto& [a, b] = tests[i];
int pos = -1;
if (a.x <= xl and b.x >= xl) {
int tl = -1;
int tr = len(lines);
while (tl + 1 < tr) {
int tm = (tl + tr) / 2;
auto& [c, d] = lines[tm];
if (get(c, d, xl) + eps < get(a, b, xl)) {
tl = tm;
} else {
tr = tm;
}
}
pos = tl;
} else if (a.x >= xl and a.x <= xr) {
pos = get_pos(a);
} else {
assert(b.x >= xl and b.x <= xr);
pos = get_pos(b);
}
if (pos >= 0) {
if (intersects(a, b, lines[pos].first, lines[pos].second)) {
result[i] = true;
}
}
if (pos + 1 < len(lines)) {
if (intersects(a, b, lines[pos + 1].first, lines[pos + 1].second)) {
result[i] = true;
}
}
if (!result[i]) {
new_ind.push_back(i);
}
}
ind = new_ind;
new_ind.clear();
}
if (xl == xr) {
return;
}
if (xl + 1 == xr) {
solve_rec(curves, ind, xl, xl);
solve_rec(curves, ind, xr, xr);
return;
}
ll xm = (xl + xr) / 2;
solve_rec(curves, ind, xl, xm);
solve_rec(curves, ind, xm, xr);
}
void solve() {
result.assign(q, false);
vector<vector<vec>> curves = { poly };
curves.push_back(vector<vec>{poly.front(), poly.back()});
vector<int> ind(q);
rep(i, q) ind[i] = i;
solve_rec(curves, ind, 0, 30000);
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> q;
poly.resize(n);
rep(i, n) cin >> poly[i].x >> poly[i].y;
tests.resize(q);
rep(i, q) {
cin >> tests[i].first.x >> tests[i].first.y >> tests[i].second.x >> tests[i].second.y;
if (tests[i].first.x > tests[i].second.x) {
swap(tests[i].first, tests[i].second);
}
}
solve();
rep(i, q) {
if (result[i]) {
cout << "YES" << "\n";
} else {
cout << "NO" << "\n";
}
}
return 0;
}
/*
4 6
1 1
4 1
4 4
1 4
0 2 2 0
0 1 1 1
0 0 5 5
2 2 4 2
2 2 3 2
5 1 0 2
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3572kb
input:
4 6 1 1 4 1 4 4 1 4 0 2 2 0 0 1 1 1 0 0 5 5 2 2 4 2 2 2 3 2 5 1 0 2
output:
YES YES YES YES NO YES
result:
ok 6 token(s): yes count is 5, no count is 1
Test #2:
score: 0
Accepted
time: 261ms
memory: 22664kb
input:
20 200000 8838 9219 12190 11292 15953 7581 16690 6159 21104 5484 8978 1076 4354 1065 1261 676 12684 14159 15469 22416 13493 28027 15531 26837 18253 26053 26444 24253 22160 19958 24879 12856 28793 22156 25300 10245 14749 15078 12946 13942 26544 28338 18806 21279 5592 29200 20935 25253 28189 17513 215...
output:
YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES NO YES NO YES YES NO YES NO YES YES YES NO YES YES YES NO YES YES YES NO YES YES YES YES YES YES YES YES YES NO NO YES YES YES YES NO NO YES YES YES YES YES YES YES YES YES YES NO YES NO YES YES YES YES YES YES YES NO NO YES YES YES YES...
result:
ok 200000 token(s): yes count is 156067, no count is 43933
Test #3:
score: 0
Accepted
time: 652ms
memory: 17220kb
input:
500 200000 17729 7936 17684 8099 17925 10195 17441 9150 17314 9604 17008 8764 17003 7525 16501 4085 16247 5851 16768 625 16492 706 15995 4316 16287 976 16032 629 15217 133 15692 4260 16153 6940 15550 5717 15493 4823 15085 4477 14465 4830 13595 4960 13721 3490 13309 2776 11167 3053 14319 2156 14626 2...
output:
YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES NO YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES Y...
result:
ok 200000 token(s): yes count is 197031, no count is 2969
Test #4:
score: 0
Accepted
time: 490ms
memory: 16320kb
input:
2000 200000 15746 1958 15965 1785 16322 2203 16779 3060 15774 2055 15869 2486 16141 3025 14987 1567 16314 3508 14816 1823 13841 1058 15595 3183 15716 4094 15939 4023 16426 4179 16507 5225 17035 6211 17233 5343 18059 5915 17140 5103 17154 4324 17471 4562 18065 5767 20733 10646 21651 12444 18707 6969 ...
output:
YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES ...
result:
ok 200000 token(s): yes count is 199151, no count is 849
Test #5:
score: 0
Accepted
time: 167ms
memory: 15248kb
input:
2000 200000 11439 4221 11601 4531 11351 4595 10165 4725 11049 4209 9643 4623 8884 4596 8598 4376 10987 3767 10577 3606 10678 3417 10159 3481 10288 3302 11157 2781 10513 2652 10601 2489 10785 2201 9881 2932 10877 1775 9578 3034 9083 3337 8118 4188 8911 3253 10649 1785 6624 3607 6002 3749 10788 1539 8...
output:
NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO ...
result:
ok 200000 token(s): yes count is 1564, no count is 198436
Test #6:
score: -100
Wrong Answer
time: 189ms
memory: 15444kb
input:
2000 200000 25931 29637 25732 29388 25090 29397 24676 29660 24268 29454 24712 28969 24252 27672 23976 28067 24211 27138 24428 27732 24389 27010 24062 26426 24278 25689 24727 26596 25281 28154 25062 26750 24927 26324 24625 25457 25456 26307 25444 25561 26008 27471 26065 27717 26065 27194 25255 24568 ...
output:
NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO YES NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO YES NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO YES NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO ...
result:
wrong answer expected YES, found NO [10809th token]