제출 #1356575

#제출 시각아이디문제언어결과실행 시간메모리
1356575vjudge1Park (BOI16_park)C++17
100 / 100
184 ms34256 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

const int MAXV = 2005;

struct DSU {
    int par[MAXV], sz[MAXV];

    void init(int n) {
        for (int i = 0; i < n; i++) {
            par[i] = i;
            sz[i] = 1;
        }
    }

    int find(int u) {
        if (par[u] == u) return u;
        return par[u] = find(par[u]);
    }

    void merge(int u, int v) {
        u = find(u);
        v = find(v);
        if (u == v) return;
        if (sz[u] < sz[v]) swap(u, v);
        par[v] = u;
        sz[u] += sz[v];
    }
};

struct Tree {
    ll x, y, r;
};

struct Event {
    ll gap;
    int u, v;

    bool operator < (const Event& other) const {
        return gap < other.gap;
    }
};

struct Query {
    ll need;
    int start, id;

    bool operator < (const Query& other) const {
        return need < other.need;
    }
};

ll getGap(const Tree& a, const Tree& b) {
    ll dx = a.x - b.x;
    ll dy = a.y - b.y;
    ll d = sqrt((long double)dx * dx + (long double)dy * dy);
    return d - a.r - b.r;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    ll w, h;
    cin >> n >> m >> w >> h;

    vector<Tree> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i].x >> a[i].y >> a[i].r;
    }

    vector<Event> events;

    auto addEdge = [&](int u, int v, ll gap) {
        events.push_back({gap, u, v});
    };

    // 0 = bottom, 1 = right, 2 = top, 3 = left
    // tree i has id = i + 4

    for (int i = 0; i < n; i++) {
        int id = i + 4;

        addEdge(id, 0, a[i].y - a[i].r);         // to bottom
        addEdge(id, 1, w - a[i].x - a[i].r);     // to right
        addEdge(id, 2, h - a[i].y - a[i].r);     // to top
        addEdge(id, 3, a[i].x - a[i].r);         // to left
    }

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            addEdge(i + 4, j + 4, getGap(a[i], a[j]));
        }
    }

    vector<Query> q(m);
    for (int i = 0; i < m; i++) {
        ll r;
        int e;
        cin >> r >> e;
        --e;
        q[i] = {2 * r, e, i};
    }

    sort(events.begin(), events.end());
    sort(q.begin(), q.end());

    static bool ok[100005][4];
    memset(ok, true, sizeof(ok));

    DSU dsu;
    dsu.init(n + 4);

    int ptr = 0;
    for (const Query& cur : q) {
        // allowed to touch
        // so only gaps < 2r are blocked
        while (ptr < (int)events.size() && events[ptr].gap < cur.need) {
            dsu.merge(events[ptr].u, events[ptr].v);
            ptr++;
        }

        bool conn[4][4];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                conn[i][j] = (dsu.find(i) == dsu.find(j));
            }
        }

        auto bad = [&](int side) {
            int prev = (side == 0 ? 3 : side - 1);
            return conn[prev][side];
        };

        bool blockHorizontal = conn[0][2];
        bool blockVertical = conn[1][3];

        for (int to = 0; to < 4; to++) {
            if (to == cur.start) continue;

            if (bad(cur.start) || bad(to)) {
                ok[cur.id][to] = false;
                continue;
            }

            if (abs(cur.start - to) == 2) {
                if (blockHorizontal || blockVertical) {
                    ok[cur.id][to] = false;
                }
            } else if (cur.start + to == 3) {
                if (blockVertical) {
                    ok[cur.id][to] = false;
                }
            } else {
                if (blockHorizontal) {
                    ok[cur.id][to] = false;
                }
            }
        }
    }

    for (int i = 0; i < m; i++) {
        string ans = "";
        for (int side = 0; side < 4; side++) {
            if (ok[i][side]) ans += char('1' + side);
        }
        cout << ans << '\n';
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...