답안 #1072363

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1072363 2024-08-23T17:32:12 Z wapas 별자리 2 (JOI14_constellation2) C++17
55 / 100
1880 ms 262144 KB
// code by wapas
# pragma GCC optimize ("O3")
# pragma GCC optimize ("Ofast")
# pragma GCC optimize ("unroll-loops")
# pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2")

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

/*
  segtree code by : https://github.com/atcoder/ac-library/blob/master/atcoder/segtree.hpp
  how to use : https://github.com/atcoder/ac-library/blob/master/document_en/segtree.md
*/
#if __cplusplus < 202002L
unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}
#endif

int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

template <class S, auto op, auto e> struct segtree {
    static_assert(is_convertible_v<decltype(op), function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(is_convertible_v<decltype(e), function<S()>>,
                  "e must work as S()");
  
  public:
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(vector<S>(n, e())) {}
    explicit segtree(const vector<S>& v) : _n(int(v.size())) {
        size = (int) bit_ceil((unsigned int)(_n));
        log = countr_zero((unsigned int)size);
        d = vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) const {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

ll op(ll a, ll b) {
    return a + b;
}

ll e() {
    return 0;
}

// Bulldozer code by justiceHui : https://justicehui.github.io/hard-algorithm/2022/03/30/rotate-sweep-line/
struct point {
    ll x, y, z;
    bool operator < (const point &p) const {
        return tie(x, y) < tie(p.x, p.y);
    }
    bool operator == (const point &p) const {
        return tie(x, y) == tie(p.x, p.y);
    }
};

struct line {
    ll i, j, dx, dy;
    line(int i, int j, const point &pi, const point &pj) : i(i), j(j), dx(pj.x - pi.x), dy(pj.y - pi.y) {}
    bool operator < (const line &l) const {
        ll le = dy * l.dx, ri = l.dy * dx;
        return tie(le, i, j) < tie(ri, l.i, l.j);
    }
    bool operator == (const line &l) const {
        return dy * l.dx == l.dy * dx;
    }
};

point vec(point a, point b) {
    return { b.x - a.x, b.y - a.y };
}

ll ccw(point a, point b, point c) {
    point u = vec(a, b);
    point v = vec(b, c);
    return u.x * v.y - u.y * v.x;
}

void solution(int t) {
    int N; cin >> N;
    vector<point> prr(N);
    for (int i = 0; i < N; i++) cin >> prr[i].x >> prr[i].y >> prr[i].z;
    sort(prr.begin(), prr.end());
    vector<segtree<ll, op, e>> st(3, segtree<ll, op, e>(N));
    for (int i = 0; i < N; i++) st[prr[i].z].set(i, 1);
    vector<int> pos(N);
    for (int i = 0; i < N; i++) pos[i] = i;
    vector<line> lrr;
    for (int i = 0; i < N - 1; i++) for (int j = i + 1; j < N; j++) lrr.emplace_back(i, j, prr[i], prr[j]);
    sort(lrr.begin(), lrr.end());
    ll ans = 0;
    for (int i = 0, j = 0; i < lrr.size(); i = j) {
        while (j < lrr.size() && lrr[i] == lrr[j]) j++;
        for (int k = i; k < j; k++) {
            int u = lrr[k].i, v = lrr[k].j;
            st[prr[pos[u]].z].set(pos[u], 0);
            st[prr[pos[v]].z].set(pos[v], 0);
            swap(pos[u], pos[v]);
            swap(prr[pos[u]], prr[pos[v]]);
            if (pos[u] > pos[v]) swap(u, v);
            st[prr[pos[u]].z].set(pos[u], 1);
            st[prr[pos[v]].z].set(pos[v], 1);
            vector<ll> L = { 0, 0, 0 };
            for (int i = 0; i < 3; i++) L[i] = st[i].prod(0, pos[u]);
            ll left = 1;
            for (int i = 0; i < 3; i++) if (i != prr[pos[u]].z) left *= L[i];
            vector<ll> R = { 0, 0, 0 };
            for (int i = 0; i < 3; i++) R[i] = st[i].prod(pos[v] + 1, N);
            ll right = 1;
            for (int i = 0; i < 3; i++) if (i != prr[pos[v]].z) right *= R[i];
            ans += left * right;
        }
    }
    cout << ans;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    // int T; cin >> T;
    int T = 1;
    for (int t = 0; t < T; t++) {
        solution(t);
    }
}

Compilation message

constellation2.cpp: In function 'void solution(int)':
constellation2.cpp:197:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  197 |     for (int i = 0, j = 0; i < lrr.size(); i = j) {
      |                            ~~^~~~~~~~~~~~
constellation2.cpp:198:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  198 |         while (j < lrr.size() && lrr[i] == lrr[j]) j++;
      |                ~~^~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 0 ms 344 KB Output is correct
3 Correct 1 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 0 ms 348 KB Output is correct
7 Correct 0 ms 348 KB Output is correct
8 Correct 0 ms 348 KB Output is correct
9 Correct 0 ms 348 KB Output is correct
10 Correct 0 ms 348 KB Output is correct
11 Correct 1 ms 344 KB Output is correct
12 Correct 0 ms 344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 1 ms 344 KB Output is correct
3 Correct 2 ms 860 KB Output is correct
4 Correct 4 ms 992 KB Output is correct
5 Correct 7 ms 1568 KB Output is correct
6 Correct 17 ms 2524 KB Output is correct
7 Correct 19 ms 2524 KB Output is correct
8 Correct 17 ms 2520 KB Output is correct
9 Correct 16 ms 2524 KB Output is correct
10 Correct 11 ms 1496 KB Output is correct
11 Correct 16 ms 2524 KB Output is correct
12 Correct 17 ms 2700 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 157 ms 17092 KB Output is correct
2 Correct 203 ms 17092 KB Output is correct
3 Correct 260 ms 17092 KB Output is correct
4 Correct 247 ms 17092 KB Output is correct
5 Correct 628 ms 66424 KB Output is correct
6 Correct 1119 ms 66480 KB Output is correct
7 Correct 1880 ms 132140 KB Output is correct
8 Runtime error 164 ms 262144 KB Execution killed with signal 9
9 Halted 0 ms 0 KB -