104302024-04-02 10:54:16szilÚthálózatbővítéscpp17Futási hiba 70/100493ms63756 KiB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

struct Point {
    ll x, y;

    bool operator==(const Point &p) {
        return x == p.x && y == p.y;
    }
};

struct Line {
    int u, v;
};

ll cross(Point p, Point q) {
    return p.x * q.y - p.y * q.x;
}

ll squared(Point p) {
    return p.x*p.x+p.y*p.y;
}

ll forog(Point a, Point b, Point c) {
    b.x -= a.x; c.x -= a.x;
    b.y -= a.y; c.y -= a.y;
    ll o = cross(b, c);
    if (o > 0) return 1;
    if (o == 0) return 0;
    if (o < 0) return -1;
}

bool operator<(const Point &p, const Point &q) {
    if ((p.x >= 0) == (q.x >= 0)) {
        ll o = cross(p, q);
        if (o == 0) return squared(p) < squared(q);
        return cross(p, q) > 0;
    }
    return (p.x >= 0) < (q.x >= 0);
}

const int MAXN = 200'001;

Point points[MAXN];
Line lines[MAXN];
bool ans[MAXN];
vector<Line> to_remove[MAXN], to_add[MAXN];
set<Line> s;
int n, ox, oy;

bool operator<(const Line &a, const Line &b) {
    Point p1 = points[a.u], q1 = points[a.v], p2 = points[b.u], q2 = points[b.v];
    if (cross(p1, q1) < 0) swap(p1, q1);
    if (cross(p2, q2) < 0) swap(p2, q2);
    if (forog(p1, q1, p2) == 0) {
        return forog(p1, q1, q2) < 0;
    }
    if (forog(p1, q1, q2) == 0) {
        return forog(p1, q1, p2) < 0;
    }
    if (forog(p1, q1, p2) == forog(p1, q1, q2)) return forog(p1, q1, p2) < 0;
    if (forog(p2, q2, p1) == forog(p2, q2, q1)) return forog(p2, q2, p1) > 0;
    throw 1;
}

void solve() {
    vector<int> indices(n);
    iota(indices.begin(), indices.end(), 1);
    sort(indices.begin(), indices.end(), [&](int i, int j){
        return points[i] < points[j];
    });
    for (int i = 0; i < n; ) {
        int j = i;
        while (j + 1 < n && cross(points[indices[i]], points[indices[j + 1]]) == 0) j++;
        for (int k = i; k <= j; k++) {
            for (Line l : to_remove[indices[k]]) {
                s.erase(l);
            }
        }
        if (indices[i] == 0) {
            auto [u, v] = *s.begin();
        }
        if (s.lower_bound({indices[i], indices[i]}) == s.begin()) {
            ans[indices[i]] = true;
        }
        for (int k = i; k <= j; k++) {
            for (Line l : to_add[indices[k]]) {
                s.insert(l);
            }
        }
        i = j + 1;
    }    
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> ox >> oy;
    for (int i = 1; i <= n; i++) {
        cin >> points[i].x >> points[i].y;
        points[i].x -= ox;
        points[i].y -= oy;
    }
    for (int i = 0; i < n-1; i++) {
        int &u = lines[i].u, &v = lines[i].v;
        cin >> u >> v;
        if (points[v] < points[u]) swap(u, v);

        ll o = cross(points[u], points[v]);
        if (o > 0) {
            to_add[u].emplace_back(lines[i]);
            to_remove[v].emplace_back(lines[i]);
        } else if (o < 0) {
            s.insert(lines[i]);
            to_remove[u].emplace_back(lines[i]);
            to_add[v].emplace_back(lines[i]);
        }
    }
    solve();
    cout << count(ans+1, ans+n+1, true) << "\n";
    for (int i = 1; i <= n; i++) {
        if (ans[i]) cout << i << " ";
    }
    return 0;
}
RészfeladatÖsszpontTesztVerdiktIdőMemória
subtask10/0
1Elfogadva9ms20756 KiB
2Elfogadva136ms33240 KiB
subtask210/10
3Elfogadva10ms23264 KiB
4Elfogadva10ms23068 KiB
5Elfogadva9ms23332 KiB
6Elfogadva9ms23568 KiB
7Elfogadva9ms23816 KiB
subtask320/20
8Elfogadva8ms23868 KiB
9Elfogadva10ms24160 KiB
10Elfogadva12ms24312 KiB
11Elfogadva17ms25088 KiB
12Elfogadva28ms26044 KiB
13Elfogadva120ms33616 KiB
14Elfogadva250ms44172 KiB
15Elfogadva21ms29852 KiB
16Elfogadva45ms35044 KiB
17Elfogadva103ms39496 KiB
subtask410/10
18Elfogadva9ms30452 KiB
19Elfogadva14ms31452 KiB
20Elfogadva16ms31516 KiB
21Elfogadva21ms33268 KiB
22Elfogadva19ms32724 KiB
subtask530/30
23Elfogadva10ms31828 KiB
24Elfogadva28ms33720 KiB
25Elfogadva10ms32208 KiB
26Elfogadva9ms32312 KiB
27Elfogadva19ms33540 KiB
28Elfogadva32ms34880 KiB
29Elfogadva46ms36276 KiB
30Elfogadva27ms35392 KiB
31Elfogadva45ms39848 KiB
32Elfogadva119ms43364 KiB
subtask60/30
33Elfogadva68ms45392 KiB
34Elfogadva37ms40028 KiB
35Elfogadva231ms52820 KiB
36Elfogadva280ms53088 KiB
37Elfogadva280ms53084 KiB
38Elfogadva377ms55992 KiB
39Elfogadva405ms56784 KiB
40Elfogadva493ms58368 KiB
41Futási hiba259ms63756 KiB
42Elfogadva248ms39124 KiB