Submission #57461902


Source Code Expand

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;
using pl = array<ll, 2>;
constexpr ll INF = 1e12 + 7;
constexpr ll mod = 1e9 + 7;
constexpr ld eps = 1e-9;
const ld PI = acos(-1);

struct Point {
    int64_t x, y;

    Point(int64_t x_, int64_t y_) : x(x_), y(y_) {}

    Point operator-(const Point &p) const {
        return Point(x - p.x, y - p.y);
    }

    int64_t cross(const Point &p) const {
        return x * p.y - y * p.x;
    }

    int64_t cross(const Point &p, const Point &q) const {
        return (p - *this).cross(q - *this);
    }

    int half() const {
        return int(y < 0 || (y == 0 && x < 0));
    }
};

std::vector<std::vector<size_t>> find_faces(std::vector<Point> vertices, std::vector<std::vector<int>> adj) {
    size_t n = vertices.size();
    std::vector<std::vector<char>> used(n);
    for (size_t i = 0; i < n; i++) {
        used[i].resize(adj[i].size());
        used[i].assign(adj[i].size(), 0);
        auto compare = [&](size_t l, size_t r) {
            Point pl = vertices[l] - vertices[i];
            Point pr = vertices[r] - vertices[i];
            if (pl.half() != pr.half())
                return pl.half() < pr.half();
            return pl.cross(pr) > 0;
        };
        std::sort(adj[i].begin(), adj[i].end(), compare);
    }
    std::vector<std::vector<size_t>> faces;
    for (size_t i = 0; i < n; i++) {
        for (size_t edge_id = 0; edge_id < adj[i].size(); edge_id++) {
            if (used[i][edge_id]) {
                continue;
            }
            std::vector<size_t> face;
            size_t v = i;
            size_t e = edge_id;
            while (!used[v][e]) {
                used[v][e] = true;
                face.push_back(v);
                size_t u = adj[v][e];
                size_t e1 = std::lower_bound(adj[u].begin(), adj[u].end(), v, [&](size_t l, size_t r) {
                    Point pl = vertices[l] - vertices[u];
                    Point pr = vertices[r] - vertices[u];
                    if (pl.half() != pr.half())
                        return pl.half() < pr.half();
                    return pl.cross(pr) > 0;
                }) - adj[u].begin() + 1;
                if (e1 == adj[u].size()) {
                    e1 = 0;
                }
                v = u;
                e = e1;
            }
            std::reverse(face.begin(), face.end());
            int sign = 0;
            for (size_t j = 0; j < face.size(); j++) {
                size_t j1 = (j + 1) % face.size();
                size_t j2 = (j + 2) % face.size();
                int64_t val = vertices[face[j]].cross(vertices[face[j1]], vertices[face[j2]]);
                if (val > 0) {
                    sign = 1;
                    break;
                } else if (val < 0) {
                    sign = -1;
                    break;
                }
            }
            if (sign <= 0) {
                faces.insert(faces.begin(), face);
            } else {
                faces.emplace_back(face);
            }
        }
    }
    return faces;
}

vector<int> p;

int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); }

void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x != y)p[x] = y;
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    ll n;
    cin >> n;
    if (!n)return cout << 0, 0;
    p.resize(n);
    iota(p.begin(), p.end(), 0);
    vector<pl> a(n);
    map<pl, int> who;
    for (auto &[x, y]: a)cin >> x >> y;
    for (int i = 0; i < n; ++i) {
        who[a[i]] = i;
    }
    vector<vector<int>> g(n);
    for (int i = 0; i < n; ++i) {
        for (int dx = -1; dx <= 1; ++dx) {
            for (int dy = -1; dy <= 1; ++dy) {
                if (!dx && !dy)continue;
                auto to = pl{a[i][0] + dx, a[i][1] + dy};
                if (who.count(to)) {
                    if (dx && dy && who.count(pl{a[i][0] + dx, a[i][1]}) &&
                        who.count(pl{a[i][0], a[i][1] + dy}))
                        continue;
                    g[i].push_back(who[to]);
                    unite(i, who[to]);
                }
            }
        }
    }
    map<ll, vector<pl>> X, Y;
    ll res = 0;
    vector<vector<int>> all(n);
    for (int v = 0; v < n; ++v)all[find(v)].push_back(v);
    for (int v = 0; v < n; ++v) {
        if (all[v].empty())continue;
        sort(all[v].begin(), all[v].end());
        vector<Point> vertices;
        vector<vector<int>> E(all[v].size());
        for (auto i: all[v])vertices.emplace_back(a[i][0], a[i][1]);
        for (int i = 0; i < all[v].size(); ++i) {
            for (auto to: g[all[v][i]]) {
                int pos = lower_bound(all[v].begin(), all[v].end(), to) - all[v].begin();
                E[i].push_back(pos);
            }
        }
        auto c = find_faces(vertices, E);
        c.erase(c.begin());
        for (auto &q: c) {
            for (auto id: q) {
                int i = all[v][id];
                X[a[i][0]].push_back({a[i][1], i});
                Y[a[i][1]].push_back({a[i][0], i});
            }
        }
    }
    for (auto &[_, v]: X)sort(v.begin(), v.end());
    for (auto &[_, v]: Y)sort(v.begin(), v.end());
    vector<char> bad(n, 0);
    for (int v = 0; v < n; ++v) {
        if (all[v].empty())continue;
        set<int> l, r, u, d;
        for (auto id: all[v]) {
            auto [x, y] = a[id];
            {
                auto it = lower_bound(X[x].begin(), X[x].end(), pl{y, INF});
                if (it != X[x].end()) {
                    auto [_, what] = *it;
                    int q = find(what);
                    if (v != q) {
                        r.insert(q);
                    }
                }
                it = upper_bound(X[x].begin(), X[x].end(), pl{y, -1});
                if (it != X[x].begin()) {
                    auto [_, what] = *(--it);
                    int q = find(what);
                    if (v != q) {
                        l.insert(q);
                    }
                }
            }
            {
                auto it = lower_bound(Y[y].begin(), Y[y].end(), pl{x, INF});
                if (it != Y[y].end()) {
                    auto [_, what] = *it;
                    int q = find(what);
                    if (v != q) {
                        u.insert(q);
                    }
                }
                it = upper_bound(Y[y].begin(), Y[y].end(), pl{x, -1});
                if (it != Y[y].begin()) {
                    auto [_, what] = *(--it);
                    int q = find(what);
                    if (v != q) {
                        d.insert(q);
                    }
                }
            }
        }
    }
    for (ll v = 0; v < n; ++v) {
        if (bad[find(v)])--res;
    }
    for (int v = 0; v < n; ++v) {
        if (all[v].empty())continue;
        if (bad[find(all[v].front())])continue;
        sort(all[v].begin(), all[v].end());
        vector<Point> vertices;
        vector<vector<int>> E(all[v].size());
        for (auto i: all[v])vertices.emplace_back(a[i][0], a[i][1]);
        for (int i = 0; i < all[v].size(); ++i) {
            for (auto to: g[all[v][i]]) {
                int pos = lower_bound(all[v].begin(), all[v].end(), to) - all[v].begin();
                E[i].push_back(pos);
            }
        }
        auto c = find_faces(vertices, E);
        c.erase(c.begin());
        for (auto &q: c) {
            for (auto &id: q)id = all[v][id];
        }
        for (auto &v: c) {
            ll S = 0;
            ll n = v.size();
            for (int i = 0; i < n; ++i) {
                S += (a[v[(i + 1) % n]][0] - a[v[i]][0]) * (a[v[(i + 1) % n]][1] + a[v[i]][1]);
            }
            S = abs(S);
            ll inside = (S + 2 - n) / 2;
            res += inside;
        }
    }


    cout << res;

}

Submission Info

Submission Time
Task G - Go Territory
User ZergTricky
Language C++ 20 (gcc 12.2)
Score 0
Code Size 8089 Byte
Status RE
Exec Time 921 ms
Memory 122140 KiB

Compile Error

Main.cpp: In function ‘int main()’:
Main.cpp:148:27: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  148 |         for (int i = 0; i < all[v].size(); ++i) {
      |                         ~~^~~~~~~~~~~~~~~
Main.cpp:220:27: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  220 |         for (int i = 0; i < all[v].size(); ++i) {
      |                         ~~^~~~~~~~~~~~~~~

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 0 / 600
Status
AC × 3
AC × 7
WA × 11
RE × 10
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, sample_01.txt, sample_02.txt, sample_03.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt
Case Name Status Exec Time Memory
random_01.txt WA 531 ms 46968 KiB
random_02.txt WA 539 ms 46884 KiB
random_03.txt WA 533 ms 46928 KiB
random_04.txt WA 655 ms 59200 KiB
random_05.txt WA 654 ms 58612 KiB
random_06.txt WA 654 ms 58428 KiB
random_07.txt WA 697 ms 61468 KiB
random_08.txt RE 549 ms 61224 KiB
random_09.txt AC 704 ms 105976 KiB
random_10.txt AC 695 ms 106028 KiB
random_11.txt RE 317 ms 36584 KiB
random_12.txt RE 383 ms 36656 KiB
random_13.txt RE 436 ms 36572 KiB
random_14.txt RE 473 ms 37324 KiB
random_15.txt WA 921 ms 122140 KiB
random_16.txt AC 429 ms 85148 KiB
random_17.txt AC 518 ms 101080 KiB
random_18.txt RE 260 ms 35228 KiB
random_19.txt RE 259 ms 35268 KiB
random_20.txt RE 260 ms 35272 KiB
sample_01.txt AC 1 ms 3644 KiB
sample_02.txt AC 1 ms 3428 KiB
sample_03.txt AC 1 ms 3564 KiB
test_00.txt RE 109 ms 5528 KiB
test_01.txt WA 55 ms 7224 KiB
test_02.txt WA 24 ms 5700 KiB
test_03.txt WA 72 ms 9272 KiB
test_04.txt RE 80 ms 3816 KiB