Submission #1072366

# Submission time Handle Problem Language Result Execution time Memory
1072366 2024-08-23T17:33:25 Z wapas 별자리 2 (JOI14_constellation2) C++17
55 / 100
1905 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, max(pos[u], 1));
            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(min(N - 1, 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++;
      |                ~~^~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 348 KB Output is correct
4 Correct 1 ms 348 KB Output is correct
5 Correct 1 ms 348 KB Output is correct
6 Correct 1 ms 348 KB Output is correct
7 Correct 0 ms 348 KB Output is correct
8 Correct 1 ms 348 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 1 ms 348 KB Output is correct
11 Correct 0 ms 344 KB Output is correct
12 Correct 0 ms 348 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Correct 2 ms 860 KB Output is correct
4 Correct 5 ms 992 KB Output is correct
5 Correct 7 ms 1500 KB Output is correct
6 Correct 21 ms 2524 KB Output is correct
7 Correct 25 ms 2524 KB Output is correct
8 Correct 16 ms 2604 KB Output is correct
9 Correct 17 ms 2520 KB Output is correct
10 Correct 12 ms 1500 KB Output is correct
11 Correct 20 ms 2660 KB Output is correct
12 Correct 18 ms 2524 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 162 ms 17092 KB Output is correct
2 Correct 196 ms 17092 KB Output is correct
3 Correct 260 ms 17092 KB Output is correct
4 Correct 254 ms 17088 KB Output is correct
5 Correct 617 ms 66472 KB Output is correct
6 Correct 1147 ms 66420 KB Output is correct
7 Correct 1905 ms 132188 KB Output is correct
8 Runtime error 156 ms 262144 KB Execution killed with signal 9
9 Halted 0 ms 0 KB -