제출 #1332499

#제출 시각아이디문제언어결과실행 시간메모리
1332499ee23b179_cpLong Distance Coach (JOI17_coach)C++20
100 / 100
107 ms23992 KiB
#include <bits/stdc++.h>
using namespace std;

using int128 = __int128_t;
const int128 INF = ((int128)1 << 100);

void print(int128 n) {
    if (n == 0) {
        cout << 0;
        return;
    }
    string s;
    while (n > 0) {
        s += (char)('0' + (int)(n % 10));
        n /= 10;
    }
    reverse(s.begin(), s.end());
    cout << s;
}

struct Passenger {
    long long d, c;
    bool operator<(const Passenger& o) const {
        return d < o.d;
    }
};

struct Line {
    int128 m, c;
    int128 eval(int128 x) {
        return m * x + c;
    }
};

struct CHT {
    deque<Line> dq;
    
    bool bad(Line l1, Line l2, Line l3) {
        return (l3.c - l1.c) * (l1.m - l2.m) <= (l2.c - l1.c) * (l1.m - l3.m);
    }
    
    void add(int128 m, int128 c) {
        Line l = {m, c};
        while (dq.size() >= 2 && bad(dq[dq.size() - 2], dq.back(), l)) {
            dq.pop_back();
        }
        dq.push_back(l);
    }
    
    int128 query(int128 x) {
        if (dq.empty()) return INF;
        int l = 0, r = dq.size() - 1;
        int128 ans = dq[0].eval(x);
        
        while (l <= r) {
            int mid = l + (r - l) / 2;
            ans = min(ans, dq[mid].eval(x));
            if (mid < (int)dq.size() - 1) {
                if (dq[mid].eval(x) > dq[mid + 1].eval(x)) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            } else {
                break;
            }
        }
        return ans;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    long long X, N, M, W, T;
    if (!(cin >> X >> N >> M >> W >> T)) return 0;

    vector<long long> S(N);
    for (int i = 0; i < N; i++) {
        cin >> S[i];
    }
    S.push_back(X);

    vector<Passenger> P(M);
    for (int i = 0; i < M; i++) {
        cin >> P[i].d >> P[i].c;
    }

    sort(P.begin(), P.end());

    int128 driver_cost = (int128)(X / T + 1) * W;

    vector<int128> prefC(M + 1, 0);
    for (int i = 0; i < M; i++) {
        prefC[i + 1] = prefC[i] + P[i].c;
    }

    vector<int128> min_q(M + 1, INF);
    for (int i = 0; i <= N; i++) {
        long long rem = S[i] % T;
        long long div = S[i] / T;
        
        Passenger dummy = {rem, 0};
        int idx = lower_bound(P.begin(), P.end(), dummy) - P.begin();
        
        if ((int128)div < min_q[idx]) {
            min_q[idx] = div;
        }
    }

    vector<int128> keep_cost(M + 1, 0);
    long long r_X = X % T;
    long long q_X = X / T;
    for (int i = 1; i <= M; i++) {
        long long drinks = q_X + (P[i - 1].d < r_X ? 1 : 0);
        keep_cost[i] = (int128)drinks * W;
    }

    vector<int128> dp(M + 1, INF);
    dp[0] = 0;

    CHT cht;
    cht.add(0, 0);

    for (int i = 1; i <= M; i++) {
        dp[i] = dp[i - 1] + keep_cost[i];
        
        if (min_q[i] != INF) {
            int128 x = min_q[i] * W;
            int128 min_val = cht.query(x);
            if (min_val != INF) {
                int128 drop_cost = min_val + prefC[i] + (int128)i * x;
                if (drop_cost < dp[i]) {
                    dp[i] = drop_cost;
                }
            }
        }
        
        if (dp[i] != INF) {
            cht.add(-i, dp[i] - prefC[i]);
        }
    }

    int128 ans = dp[M] + driver_cost;
    print(ans);
    cout << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...