結果

問題 No.448 ゆきこーだーの雨と雪 (3)
ユーザー まいん-まいん-
提出日時 2017-03-13 00:39:26
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 1,745 ms / 2,000 ms
コード長 2,856 bytes
コンパイル時間 668 ms
コンパイル使用メモリ 67,236 KB
実行使用メモリ 15,872 KB
最終ジャッジ日時 2024-10-12 23:17:45
合計ジャッジ時間 31,004 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 1 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 4 ms
5,248 KB
testcase_05 AC 5 ms
5,248 KB
testcase_06 AC 9 ms
5,248 KB
testcase_07 AC 4 ms
5,248 KB
testcase_08 AC 5 ms
5,248 KB
testcase_09 AC 6 ms
5,248 KB
testcase_10 AC 3 ms
5,248 KB
testcase_11 AC 7 ms
5,248 KB
testcase_12 AC 7 ms
5,248 KB
testcase_13 AC 224 ms
5,248 KB
testcase_14 AC 260 ms
5,248 KB
testcase_15 AC 665 ms
8,704 KB
testcase_16 AC 1,114 ms
12,928 KB
testcase_17 AC 1,206 ms
13,440 KB
testcase_18 AC 187 ms
6,816 KB
testcase_19 AC 1,523 ms
14,948 KB
testcase_20 AC 556 ms
7,040 KB
testcase_21 AC 1,546 ms
15,216 KB
testcase_22 AC 579 ms
8,064 KB
testcase_23 AC 1,553 ms
15,104 KB
testcase_24 AC 367 ms
6,144 KB
testcase_25 AC 1,530 ms
14,976 KB
testcase_26 AC 173 ms
5,248 KB
testcase_27 AC 1,165 ms
13,056 KB
testcase_28 AC 1,095 ms
10,624 KB
testcase_29 AC 592 ms
8,192 KB
testcase_30 AC 1,601 ms
15,424 KB
testcase_31 AC 226 ms
5,248 KB
testcase_32 AC 253 ms
5,248 KB
testcase_33 AC 1,701 ms
15,872 KB
testcase_34 AC 1,686 ms
15,872 KB
testcase_35 AC 1,692 ms
15,872 KB
testcase_36 AC 1,700 ms
15,872 KB
testcase_37 AC 1,745 ms
15,872 KB
testcase_38 AC 1,696 ms
15,792 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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

using ll = long long;

template <typename T>
struct SegmentTree {
    const T DEFULT_VAL = -1;

    vector<T> dat;
    int end;

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

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

        for (int id = 2 * end - 2; id >= 0; id--) {
            if (2 * end - 2 - id < end) {
                int idx = id - end + 1;
                dat[id] = idx < n ? d[idx] : DEFULT_VAL;
            } else {
                dat[id] = max(dat[id * 2 + 1], dat[id * 2 + 2]);
            }
        }
    }

    void update(int idx, T a) {
        int id = idx + end - 1;
        dat[id] = a;
        while (id > 0) {
            id = (id - 1) / 2;
            dat[id] = max(dat[id * 2 + 1], dat[id * 2 + 2]);
        }
    }

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

    T query(int lb, int ub, int id, int node_lb, int node_ub) {
        if (node_ub <= lb || ub <= node_lb) { return DEFULT_VAL; }

        if (lb <= node_lb && node_ub <= ub) { return dat[id]; }
        else {
            int 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 max(vl, vr);
        }
    }
};

const ll INF = (1LL << 60);
const int MAX_N = 200010;

int n, next_node[MAX_N];

ll k;
vector<ll> t, d, table, cum_d, max_d;

void calc_dp(ll ub) {
    fill(table.begin(), table.end(), INF);
    table[0] = 0;

    for (int i = 0; i < n; i++) {
        if (d[i] <= ub) {
            table[i + 1] = min(table[i + 1], table[i] + d[i]);
        }
        if (max_d[i] <= ub) {
            int next = next_node[i];
            table[next] = min(table[next],
                              table[i] + cum_d[next - 1] - cum_d[i]);
        }
    }
}

int main() {
    cin >> n >> k;

    t.resize(n);
    d.resize(n);
    table.resize(n + 1);
    cum_d.resize(n, 0);
    max_d.resize(n, 0);

    for (int i = 0; i < n; i++) {
        cin >> t[i] >> d[i];

        cum_d[i] = d[i];
        if (i > 0) {
            cum_d[i] += cum_d[i - 1];
        }
    }

    SegmentTree<ll> segtree(d);

    for (int i = 0; i < n; i++) {
        next_node[i] = lower_bound(t.begin() + i + 1, t.begin() + n, t[i] + k) - t.begin();
        max_d[i] = segtree.query(i + 1, next_node[i]);

        cerr << "(" << next_node[i] << ", " << max_d[i] << ")" << endl;
    }

    ll lb = -1, ub = INF, sum = 0;
    while (ub - lb > 1) {
        ll mid = (ub + lb) / 2;
        calc_dp(mid);
        if (table[n] < INF) {
            ub = mid;
            sum = table[n];
        } else {
            lb = mid;
        }
    }
    cout << ub << endl;
    cout << sum << endl;

    return 0;
}
0