結果

問題 No.704 ゴミ拾い Medium
ユーザー tsutajtsutaj
提出日時 2018-06-15 23:44:05
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,906 bytes
コンパイル時間 1,051 ms
コンパイル使用メモリ 108,056 KB
実行使用メモリ 29,128 KB
最終ジャッジ日時 2024-06-30 15:34:19
合計ジャッジ時間 11,459 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 7 ms
19,784 KB
testcase_01 AC 7 ms
19,776 KB
testcase_02 AC 7 ms
19,784 KB
testcase_03 AC 7 ms
19,776 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
testcase_33 WA -
testcase_34 AC 336 ms
28,872 KB
testcase_35 AC 331 ms
28,920 KB
testcase_36 WA -
testcase_37 AC 327 ms
28,836 KB
testcase_38 WA -
testcase_39 WA -
testcase_40 AC 327 ms
28,996 KB
testcase_41 AC 328 ms
28,912 KB
testcase_42 AC 329 ms
28,996 KB
testcase_43 AC 330 ms
28,996 KB
testcase_44 AC 7 ms
19,780 KB
testcase_45 AC 7 ms
19,912 KB
testcase_46 AC 369 ms
28,956 KB
testcase_47 AC 383 ms
28,996 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// 基本テンプレート
 
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
using namespace std;
 
#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

// Abstract Segment Tree (抽象・汎化セグメント木)
// Verified: AOJ DSL_2_A: Range Minimum Query (int型のみ)

const int SIZE = 1 << 19;
template<typename T>
struct segtree {
    // ノード、単位元
    T node[2*SIZE], I;

    // オペレーション (update, query の 2 つが必要?)
    T (*upd_f)(T, T), (*qry_f)(T, T);

    // 演算子と単位元をセットし、全ての node を単位元で初期化
    segtree(T (*op1)(T, T), T (*op2)(T, T), T X) {
        upd_f = op1;
        qry_f = op2;
        I = X;
        fill(node, node+2*SIZE, I);
    }

    // 配列 vec の値で初期化
    void init(vector<T> vec) {
        int N = (int)vec.size();
        for(int i=0; i<N; i++) {
            node[SIZE-1+i] = vec[i];
        }
        for(int i=SIZE-2; i>=0; i--) {
            node[i] = qry_f(node[2*i+1], node[2*i+2]);
        }
    }

    // 場所 idx に値 val を反映 (upd_f を用いて update)
    void update(int idx, T val) {
        idx += SIZE - 1;
        node[idx] = upd_f(node[idx], val);
        while(idx > 0) {
            // 登るときは qry_f を使うことに注意!!!
            idx = (idx - 1) / 2;
            node[idx] = qry_f(node[2*idx+1], node[2*idx+2]);
        }
    }

    // 半開区間 [a, b) に対してクエリを投げる
    // (qry_f を用いて処理)
    T query(int a, int b, int l=0, int r=SIZE, int k=0) {
        if(b <= l || r <= a) return I;
        if(a <= l && r <= b) return node[k];
        int mid = (l + r) / 2;
        T vl = query(a, b, l, mid, 2*k+1);
        T vr = query(a, b, mid, r, 2*k+2);
        return qry_f(vl, vr);
    }
};

// [[つかいかた]]
// update 用と query 用の関数と単位元 (関数を噛ませても結果が変わらないもの) を用意して宣言する
// 下の例だと、update 用の関数が upd で、query 用の関数が fnd で、単位元が INT_MAX

int upd(int a, int b) {return b;}
int fnd(int a, int b) {return min(a, b);}
segtree<int> seg_minus(upd, fnd, 1LL << 60);
segtree<int> seg_plus(upd, fnd, 1LL << 60);
 
signed main() {
    int N; cin >> N;
    vector<int> A(N+1), X(N+1), Y(N+1);
    for(int i=0; i<N; i++) cin >> A[i+1];
    for(int i=0; i<N; i++) cin >> X[i+1];
    for(int i=0; i<N; i++) cin >> Y[i+1];

    vector<int> dp(N+1, INF);
    dp[0] = 0;

    int it = 1;
    for(int i=1; i<=N; i++) {
        dp[i] = dp[i-1] + abs(A[i] - X[i]) + Y[i];
        chmin(dp[i], seg_minus.query(0, i) + A[i]);
        chmin(dp[i], seg_plus.query(0, i) - A[i]);
        seg_plus.update(i, dp[i-1] + Y[i] + X[i]);

        while(it <= N && X[it] < A[i+1]) {
            int val = seg_plus.query(it, it+1) - 2 * X[it];
            seg_plus.update(it, INF);
            seg_minus.update(it, val);
            it++;
        }
    }
    cout << dp[N] << endl;
    return 0;
}
0