結果

問題 No.448 ゆきこーだーの雨と雪 (3)
ユーザー まいん-まいん-
提出日時 2017-03-13 00:43:46
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 121 ms / 2,000 ms
コード長 2,833 bytes
コンパイル時間 733 ms
コンパイル使用メモリ 66,680 KB
実行使用メモリ 15,864 KB
最終ジャッジ日時 2024-06-30 00:36:36
合計ジャッジ時間 5,535 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,944 KB
testcase_02 AC 2 ms
6,940 KB
testcase_03 AC 1 ms
6,944 KB
testcase_04 AC 2 ms
6,940 KB
testcase_05 AC 2 ms
6,944 KB
testcase_06 AC 2 ms
6,944 KB
testcase_07 AC 2 ms
6,940 KB
testcase_08 AC 2 ms
6,940 KB
testcase_09 AC 2 ms
6,940 KB
testcase_10 AC 1 ms
6,944 KB
testcase_11 AC 1 ms
6,944 KB
testcase_12 AC 2 ms
6,944 KB
testcase_13 AC 18 ms
6,940 KB
testcase_14 AC 21 ms
6,944 KB
testcase_15 AC 50 ms
8,576 KB
testcase_16 AC 81 ms
12,840 KB
testcase_17 AC 84 ms
13,348 KB
testcase_18 AC 14 ms
6,940 KB
testcase_19 AC 112 ms
14,956 KB
testcase_20 AC 39 ms
7,040 KB
testcase_21 AC 114 ms
15,060 KB
testcase_22 AC 40 ms
8,064 KB
testcase_23 AC 111 ms
15,216 KB
testcase_24 AC 27 ms
6,940 KB
testcase_25 AC 109 ms
15,004 KB
testcase_26 AC 13 ms
6,944 KB
testcase_27 AC 81 ms
13,008 KB
testcase_28 AC 73 ms
10,496 KB
testcase_29 AC 43 ms
8,320 KB
testcase_30 AC 111 ms
15,224 KB
testcase_31 AC 16 ms
6,944 KB
testcase_32 AC 18 ms
6,940 KB
testcase_33 AC 121 ms
15,864 KB
testcase_34 AC 116 ms
15,736 KB
testcase_35 AC 117 ms
15,796 KB
testcase_36 AC 113 ms
15,864 KB
testcase_37 AC 118 ms
15,796 KB
testcase_38 AC 117 ms
15,820 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 << 48);
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.tie(0);
    ios::sync_with_stdio(false);

    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]);
    }

    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