結果
問題 | No.1874 Minimum of Sum of Rectangles |
ユーザー | Cyanmond |
提出日時 | 2022-03-02 14:35:46 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 709 ms / 3,000 ms |
コード長 | 6,655 bytes |
コンパイル時間 | 2,793 ms |
コンパイル使用メモリ | 229,812 KB |
実行使用メモリ | 25,028 KB |
最終ジャッジ日時 | 2024-09-19 02:06:52 |
合計ジャッジ時間 | 20,272 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 3 ms
5,376 KB |
testcase_05 | AC | 89 ms
5,864 KB |
testcase_06 | AC | 94 ms
5,736 KB |
testcase_07 | AC | 91 ms
6,940 KB |
testcase_08 | AC | 85 ms
6,940 KB |
testcase_09 | AC | 157 ms
6,940 KB |
testcase_10 | AC | 156 ms
6,940 KB |
testcase_11 | AC | 158 ms
6,944 KB |
testcase_12 | AC | 156 ms
6,944 KB |
testcase_13 | AC | 159 ms
6,944 KB |
testcase_14 | AC | 678 ms
24,852 KB |
testcase_15 | AC | 688 ms
24,812 KB |
testcase_16 | AC | 681 ms
24,896 KB |
testcase_17 | AC | 653 ms
24,832 KB |
testcase_18 | AC | 669 ms
24,868 KB |
testcase_19 | AC | 670 ms
24,992 KB |
testcase_20 | AC | 643 ms
24,816 KB |
testcase_21 | AC | 679 ms
24,784 KB |
testcase_22 | AC | 679 ms
24,908 KB |
testcase_23 | AC | 647 ms
24,856 KB |
testcase_24 | AC | 677 ms
24,884 KB |
testcase_25 | AC | 689 ms
24,844 KB |
testcase_26 | AC | 691 ms
24,936 KB |
testcase_27 | AC | 663 ms
24,812 KB |
testcase_28 | AC | 646 ms
24,880 KB |
testcase_29 | AC | 709 ms
24,888 KB |
testcase_30 | AC | 680 ms
24,812 KB |
testcase_31 | AC | 674 ms
24,820 KB |
testcase_32 | AC | 685 ms
25,028 KB |
testcase_33 | AC | 634 ms
24,996 KB |
testcase_34 | AC | 2 ms
6,940 KB |
testcase_35 | AC | 2 ms
6,944 KB |
testcase_36 | AC | 2 ms
6,940 KB |
testcase_37 | AC | 156 ms
6,944 KB |
testcase_38 | AC | 156 ms
6,944 KB |
testcase_39 | AC | 156 ms
6,940 KB |
testcase_40 | AC | 155 ms
6,944 KB |
testcase_41 | AC | 160 ms
6,940 KB |
ソースコード
#include <bits/stdc++.h> using i64 = int64_t; std::vector<int> press(std::vector<int> &vec) { auto p = vec; std::sort(p.begin(), p.end()); p.erase(std::unique(p.begin(), p.end()), p.end()); for (auto &e : vec) e = (int)(std::lower_bound(p.begin(), p.end(), e) - p.begin()); return p; } template <class M> struct SegmentTree { using T = typename M::Type; int n, size; std::vector<T> data; SegmentTree(int n_) : n(n_) { size = 1; while (size < n) size <<= 1; data.assign(2 * size, M::id()); } void set(int i, const T val) { assert(0 <= i and i < n); i += size; data[i] = val; while (i != 1) { i >>= 1; data[i] = M::op(data[2 * i], data[2 * i + 1]); } } T get(int i) { assert(0 <= i and i < n); i += size; return data[i]; } T fold(int l, int r) { assert(0 <= l and l <= r and r <= n); T pl = M::id(), pr = M::id(); for (l += size, r += size; l < r; l >>= 1, r >>= 1) { if (l & 1) pl = M::op(pl, data[l++]); if (r & 1) pr = M::op(data[--r], pr); } return M::op(pl, pr); } T fold() { return data[1]; } template <class F> int calc_max_right(int l, const F &f) { assert(0 <= l and l <= n); assert(f(M::id())); if (l == n) return n; l += size; T product = M::id(); do { while (l % 2 == 0) l >>= 1; if (not f(M::op(product, data[l]))) { while (l < size) { l <<= 1; if (f(M::op(product, data[l]))) product = M::op(product, data[l++]); } return l - size; } product = M::op(product, data[l++]); } while ((l & -l) != l); return n; } }; struct M1 { struct Type { i64 u; i64 l; int cu; int cl; }; static Type op(const Type a, const Type b) { return { a.u + b.u, a.l + b.l, a.cu + b.cu, a.cl + b.cl, }; } static Type id() { return {0, 0, 0, 0}; } }; struct M2 { struct Type { i64 a; i64 b; }; static Type op(const Type a, const Type b) { return {a.a + b.a, a.b + b.b}; } static Type id() { return {0, 0}; } }; struct M3 { using Type = i64; static Type op(const Type a, const Type b) { return a + b; } static Type id() { return 0; } }; constexpr int max_xy = 1000000; int main() { int N; std::cin >> N; std::vector<int> X(N), Y(N); for (int i = 0; i < N; ++i) std::cin >> X[i] >> Y[i]; auto get_list = [&]() { const auto x_p = press(X), y_p = press(Y); const int sx = (int)x_p.size(), sy = (int)y_p.size(); SegmentTree<M1> seg(sy); for (int i = 0; i < N; ++i) { seg.set(Y[i], M1::op(seg.get(Y[i]), {0, x_p[X[i]], 0, 1})); } std::vector<std::vector<int>> events(sx); for (int i = 0; i < N; ++i) events[X[i]].push_back(i); auto calc_sum = [&](const M1::Type v, const int x) { return ((i64)v.cu * x_p[x] - v.u) + (v.l - (i64)v.cl * x_p[x]); }; std::vector<std::pair<int, int>> points; points.reserve(sx); for (int x = 0; x < sx; ++x) { for (const int i : events[x]) { auto v = seg.get(Y[i]); v.l -= x_p[X[i]]; --v.cl; v.u += x_p[X[i]]; ++v.cu; seg.set(Y[i], v); } const i64 all_sum = calc_sum(seg.fold(), x); auto f = [&](M1::Type v) { const i64 sum = calc_sum(v, x); return 2 * sum <= all_sum; }; const int r = seg.calc_max_right(0, f); if (r == 0) { points.push_back({x, r}); } else if (r == sy) { points.push_back({x, r - 1}); } else { const i64 v1 = calc_sum(seg.fold(0, r), x), v2 = calc_sum(seg.fold(0, r + 1), x); if (2 * v1 == all_sum) points.push_back({x, r - 1}); else points.push_back({x, r}); } } for (int i = 0; i < N; ++i) { X[i] = x_p[X[i]]; Y[i] = y_p[Y[i]]; } for (auto &[x, y] : points) { x = x_p[x]; y = y_p[y]; } return points; }; auto points = get_list(); const int M = (int)points.size(); std::vector<i64> res(M); auto rotate = [&]() { auto conv = [&](int &x, int &y) { const int nx = max_xy - y; const int ny = x; x = nx; y = ny; }; for (int i = 0; i < N; ++i) conv(X[i], Y[i]); for (auto &[x, y] : points) conv(x, y); }; auto run = [&]() { const auto x_p = press(X), y_p = press(Y); const int sx = (int)x_p.size(), sy = (int)y_p.size(); for (auto &[x, y] : points) { x = (int)(std::lower_bound(x_p.begin(), x_p.end(), x) - x_p.begin()); y = (int)(std::lower_bound(y_p.begin(), y_p.end(), y) - y_p.begin()); } SegmentTree<M2> seg_f(sy); SegmentTree<M3> seg_s(sy), seg_c(sy); std::vector<std::vector<int>> event_a(sx), event_q(sx); for (int i = 0; i < N; ++i) event_a[X[i]].push_back(i); for (int i = 0; i < M; ++i) event_q[points[i].first].push_back(i); for (int x = 0; x < sx; ++x) { for (const int i : event_a[x]) { const int y = Y[i]; seg_f.set(y, M2::op(seg_f.get(y), {y_p[y], -((i64)y_p[y] * x_p[x])})); seg_s.set(y, seg_s.get(y) + x_p[x]); seg_c.set(y, seg_c.get(y) + 1); } for (const int i : event_q[x]) { const int y = points[i].second; i64 sum = (seg_c.fold(0, y) * x_p[x] - seg_s.fold(0, y)) * y_p[y]; const auto f = seg_f.fold(0, y); sum -= x_p[x] * f.a + f.b; res[i] += sum; } } for (int i = 0; i < N; ++i) { X[i] = x_p[X[i]]; Y[i] = y_p[Y[i]]; } for (auto &[x, y] : points) { x = x_p[x]; y = y_p[y]; } }; for ([[maybe_unused]] int i = 0; i < 4; ++i) { run(); rotate(); } std::cout << *std::min_element(res.begin(), res.end()) << std::endl; }