結果

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

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,944 KB
testcase_02 AC 1 ms
6,944 KB
testcase_03 AC 1 ms
6,944 KB
testcase_04 AC 5 ms
6,944 KB
testcase_05 AC 5 ms
6,944 KB
testcase_06 AC 9 ms
6,944 KB
testcase_07 AC 4 ms
6,944 KB
testcase_08 AC 5 ms
6,944 KB
testcase_09 AC 7 ms
6,944 KB
testcase_10 AC 4 ms
6,940 KB
testcase_11 AC 7 ms
6,944 KB
testcase_12 AC 7 ms
6,940 KB
testcase_13 AC 246 ms
6,940 KB
testcase_14 AC 278 ms
6,948 KB
testcase_15 AC 717 ms
8,576 KB
testcase_16 AC 1,202 ms
12,960 KB
testcase_17 AC 1,307 ms
13,420 KB
testcase_18 AC 204 ms
6,940 KB
testcase_19 AC 1,679 ms
15,120 KB
testcase_20 AC 588 ms
7,040 KB
testcase_21 AC 1,676 ms
15,188 KB
testcase_22 AC 604 ms
8,064 KB
testcase_23 AC 1,690 ms
15,268 KB
testcase_24 AC 392 ms
6,944 KB
testcase_25 AC 1,690 ms
15,088 KB
testcase_26 AC 185 ms
6,940 KB
testcase_27 AC 1,217 ms
12,960 KB
testcase_28 AC 1,147 ms
10,624 KB
testcase_29 AC 652 ms
8,192 KB
testcase_30 AC 1,715 ms
15,260 KB
testcase_31 AC 245 ms
6,944 KB
testcase_32 AC 274 ms
6,944 KB
testcase_33 AC 1,839 ms
15,976 KB
testcase_34 AC 1,821 ms
15,908 KB
testcase_35 AC 1,841 ms
15,768 KB
testcase_36 AC 1,844 ms
15,872 KB
testcase_37 AC 1,859 ms
15,800 KB
testcase_38 AC 1,841 ms
15,872 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