QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#557101 | #6403. Master of Polygon | pandapythoner | WA | 341ms | 27328kb | C++23 | 7.3kb | 2024-09-11 03:09:36 | 2024-09-11 03:09:36 |
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) {}
bool operator==(const vec& other) const {
return x == other.x and y == other.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 (make_pair(a.x, a.y) < make_pair(b.x, b.y)) 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;
new_ind.clear();
if (curves.empty() or ind.empty()) {
return;
}
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) {
if (a.first == b.first) {
return (a.second - a.first) % (b.second - b.first) > 0;
}
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 (c.x == d.x) {
if (a.y < c.y) {
tl = tm;
} else {
tr = tm;
}
} else {
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 a.x <= xr) {
pos = get_pos(a);
} else if (b.x >= xl and b.x <= xr) {
pos = get_pos(b);
} else {
assert(a.x < xl and b.x > xr);
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;
}
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.front().push_back(poly.front());
vector<int> ind(q);
rep(i, q) ind[i] = i;
solve_rec(curves, ind, 0, 30000);
}
bool good_coord(ll x) {
return 0 <= x and x <= 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;
assert(good_coord(poly[i].x));
}
tests.resize(q);
rep(i, q) {
cin >> tests[i].first.x >> tests[i].first.y >> tests[i].second.x >> tests[i].second.y;
assert(good_coord(tests[i].first.x));
assert(good_coord(tests[i].second.x));
if (make_pair(tests[i].first.x, tests[i].first.y) >
make_pair(tests[i].second.x, tests[i].second.y)) {
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
*/
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3632kb
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: -100
Wrong Answer
time: 341ms
memory: 27328kb
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:
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:
wrong answer expected YES, found NO [1st token]