QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#557131#6403. Master of PolygonpandapythonerWA 821ms22584kbC++238.5kb2024-09-11 04:40:332024-09-11 04:40:33

Judging History

你现在查看的是最新测评结果

  • [2024-09-11 04:40:33]
  • 评测
  • 测评结果:WA
  • 用时:821ms
  • 内存:22584kb
  • [2024-09-11 04:40:33]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

#define double ld
#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-5;

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 ((a - c) % (b - c) != 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;
}


bool intersects(const pair<vec, vec>& p, const pair<vec, vec>& q) {
    return intersects(p.first, p.second, q.first, q.second);
}


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);
    auto comp = [&](pair<vec, vec> a, pair<vec, vec> b) -> bool {
        int coeff = 1;
        if (a.first.x > b.first.x or a.first == a.second) {
            swap(a, b);
            coeff = -1;
        }
        if (a.first.x == a.second.x and b.first.x == b.second.x) {
            return a.first.y * coeff < b.first.y * coeff;
        }
        if (a.first == b.first) {
            return (a.second - a.first) % (b.second - a.first) * coeff > 0;
        }
        return (a.second - a.first) % (b.first - a.first) * coeff > 0;
        };
    sort(all(lines), comp);
    if (!lines.empty()) {
        for (auto i : ind) {
            auto& [a, b] = tests[i];
            int tl = -1;
            int tr = len(lines);
            while (tl + 1 < tr) {
                int tm = (tl + tr) / 2;
                auto& [c, d] = lines[tm];
                if (intersects(lines[tm], tests[i])) {
                    result[i] = true;
                    break;
                }
                if (comp(lines[tm], tests[i])) {
                    tl = tm;
                } else {
                    tr = tm;
                }
            }
            if (result[i]) continue;
            int 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;
}


void stress() {
    int c = 0;
    while (1) {
        cout << ++c << "\n";
        int mx = 100;
        n = rnd() % mx + 1;
        q = rnd() % mx + 1;
        poly.resize(n);
        rep(i, n) {
            if (i == 0 or i == n - 1) {
                poly[i].x = 2;
            } else {
                poly[i].x = rnd() % mx + 3;
            }
            poly[i].y = i;
            // swap(poly[i].x, poly[i].y);
        }
        tests.resize(q);
        rep(i, q) {
            tests[i].first.x = rnd() % mx;
            tests[i].first.y = rnd() % mx;
            tests[i].second.x = rnd() % mx;
            tests[i].second.y = rnd() % mx;
            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_slow();
        auto right_rs = result;
        solve();
        auto my_rs = result;
        if (right_rs != my_rs) {
            cout << n << " " << q << "\n";
            rep(i, n) {
                cout << poly[i].x << " " << poly[i].y << "\n";
            }
            rep(i, q) {
                cout << tests[i].first.x << " " << tests[i].first.y << " " << tests[i].second.x << " " << tests[i].second.y << "\n";
            }
            break;
        }
    }
}


signed main() {
    // stress();
    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;
}


/*
3 1
2 0
6 1
2 2
1 4 4 1

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: 3568kb

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: 320ms
memory: 22584kb

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: 821ms
memory: 17036kb

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: 614ms
memory: 16540kb

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: 198ms
memory: 15352kb

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: 0
Accepted
time: 227ms
memory: 15260kb

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:

ok 200000 token(s): yes count is 5859, no count is 194141

Test #7:

score: -100
Wrong Answer
time: 503ms
memory: 15436kb

input:

2000 200000
14066 4014
14235 4742
15201 5329
15389 5460
11381 3722
12856 4511
8264 2372
13039 4278
11684 3711
12888 4180
11849 3607
11431 3373
9979 2823
9099 2534
9055 2434
9393 2382
9867 2512
10315 2558
8175 1662
6480 184
5437 92
4413 100
5548 790
4362 471
4463 552
4817 748
6715 1673
5807 1562
7942...

output:

NO
YES
YES
NO
YES
NO
NO
YES
NO
YES
NO
NO
NO
YES
NO
NO
NO
YES
NO
YES
YES
YES
YES
NO
YES
YES
NO
NO
NO
NO
YES
NO
NO
YES
NO
NO
YES
NO
YES
YES
NO
NO
YES
NO
YES
NO
NO
NO
NO
NO
NO
NO
NO
NO
NO
NO
NO
YES
NO
NO
YES
NO
NO
NO
NO
NO
NO
NO
NO
NO
YES
NO
NO
NO
YES
NO
NO
NO
NO
YES
NO
NO
YES
NO
NO
YES
NO
NO
NO
NO
NO
...

result:

wrong answer expected YES, found NO [32841st token]