結果

問題 No.511 落ちゲー 〜手作業のぬくもり〜
ユーザー ふーらくたるふーらくたる
提出日時 2017-12-18 22:24:42
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 2,039 ms / 4,000 ms
コード長 3,647 bytes
コンパイル時間 1,058 ms
コンパイル使用メモリ 76,564 KB
実行使用メモリ 12,880 KB
最終ジャッジ日時 2024-05-03 12:44:48
合計ジャッジ時間 10,366 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 1 ms
5,376 KB
testcase_04 AC 1 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 1 ms
5,376 KB
testcase_10 AC 2 ms
5,376 KB
testcase_11 AC 2 ms
5,376 KB
testcase_12 AC 2 ms
5,376 KB
testcase_13 AC 2 ms
5,376 KB
testcase_14 AC 1 ms
5,376 KB
testcase_15 AC 1 ms
5,376 KB
testcase_16 AC 2 ms
5,376 KB
testcase_17 AC 2 ms
5,376 KB
testcase_18 AC 1 ms
5,376 KB
testcase_19 AC 1 ms
5,376 KB
testcase_20 AC 2 ms
5,376 KB
testcase_21 AC 8 ms
5,376 KB
testcase_22 AC 6 ms
5,376 KB
testcase_23 AC 8 ms
5,376 KB
testcase_24 AC 3 ms
5,376 KB
testcase_25 AC 6 ms
5,376 KB
testcase_26 AC 3 ms
5,376 KB
testcase_27 AC 11 ms
5,376 KB
testcase_28 AC 13 ms
5,376 KB
testcase_29 AC 2,039 ms
12,628 KB
testcase_30 AC 1,762 ms
12,260 KB
testcase_31 AC 1,195 ms
11,612 KB
testcase_32 AC 754 ms
12,624 KB
testcase_33 AC 230 ms
7,140 KB
testcase_34 AC 383 ms
6,244 KB
testcase_35 AC 870 ms
12,880 KB
testcase_36 AC 874 ms
12,748 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long

// Range Sum Query and Range Add Query
template <typename T>
struct LazySegmentTree {
    const T DEFULT_VAL = 0;

    vector<T> dat;
    vector<T> lazy;
    int end;

    LazySegmentTree(vector<T>& d) {
        int n = d.size();
        end = 1;
        while (end < n) end *= 2;

        dat.resize(2 * end - 1, DEFULT_VAL);
        lazy.resize(2 * end - 1, 0);

        for (int i = 0; i < d.size(); i++) {
            dat[i + end - 1] = d[i];
        }
        for (int i = end - 2; i >= 0; i--) {
            dat[i] = dat[2 * i + 1] + dat[2 * i + 2];
        }
    }

    void inline eval(int id, int node_lb, int node_ub) {
        if (lazy[id] != 0) {    // 伝搬するべき値がある
            dat[id] += lazy[id];

            if (node_ub - node_lb > 1) {
                lazy[2 * id + 1] += lazy[id] / 2;
                lazy[2 * id + 2] += lazy[id] / 2;
            }

            lazy[id] = 0;
        }
    }

    void inline add(int lb, int ub, T a) {
        add(lb, ub, a, 0, 0, end);
    }

    void inline add(int lb, int ub, T a, int id, int node_lb, int node_ub) {
        eval(id, node_lb, node_ub);

        if (node_ub <= lb || ub <= node_lb) { return; }

        if (lb <= node_lb && node_ub <= ub) {
            lazy[id] += (node_ub - node_lb) * a;
            eval(id, node_lb, node_ub);
        } else {
            add(lb, ub, a, id * 2 + 1, node_lb, (node_lb + node_ub) / 2);
            add(lb, ub, a, id * 2 + 2, (node_lb + node_ub) / 2, node_ub);
            dat[id] = dat[2 * id + 1] + dat[2 * id + 2];
        }
    }

    T inline query(int idx) {
        return query(idx, idx + 1);
    }

    T inline query(int lb, int ub) {
        return query(lb, ub, 0, 0, end);
    }

    T inline query(int lb, int ub, int id, int node_lb, int node_ub) {
        eval(id, node_lb, node_ub);

        if (node_ub <= lb || ub <= node_lb) { return DEFULT_VAL; }

        if (lb <= node_lb && node_ub <= ub) { return dat[id]; }
        else {
            T  vl = query(lb, ub, id * 2 + 1, node_lb, (node_lb + node_ub) / 2),
               vr = query(lb, ub, id * 2 + 2, (node_lb + node_ub) / 2, node_ub);
            return vl + vr;
        }
    }
};

signed main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

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

    vector<int> a(n), b(n), x(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> b[i] >> x[i];
        x[i]--;
    }

    vector<int> ng(w), ok(w);   // 各x_iごとに得点が得られたクエリ番号を二分探索
    vector<int> id(w);
    for (int i = 0; i < w; i++) {
        ng[i] = -1;
        ok[i] = n + 1;

        id[i] = i;
    }

    // 並列二分探索
    for (int loop = 0; loop < 20; loop++) {
        sort(id.begin(), id.end(), [&](int i, int j) {
            return (ng[i] + ok[i]) / 2 < (ng[j] + ok[j]) / 2;
        });
        vector<int> blocks(w, 0);
        LazySegmentTree<int> segtree(blocks);

        int ptr = 0;
        for (int i : id) {
            int mid = (ng[i] + ok[i]) / 2;
            while (ptr <= min(n - 1, mid)) {
                segtree.add(x[ptr], x[ptr] + a[ptr], b[ptr]);
                ptr++;
            }
            if (segtree.query(i) >= h) ok[i] = mid;
            else ng[i] = mid;
        }
    }

    int A = 0;
    int B = 0;
    for (int i = 0; i < w; i++) {
        if (ok[i] > n) continue;
        if (ok[i] % 2 == 0) A++;
        else B++;
    }

    if (A > B) cout << "A" << endl;
    else if (A == B) cout << "DRAW" << endl;
    else cout << "B" << endl;

    return 0;
}
0