1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  | // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
struct FenwickMax {
    int n;
    vector<long long> bit;
    static constexpr long long NEG_INF = -(1LL<<60);
    FenwickMax() {}
    FenwickMax(int n): n(n), bit(n+1, NEG_INF) {}
    void init(int n_) { n = n_; bit.assign(n+1, NEG_INF); }
    void update(int idx, long long val) {
        for (int i = idx; i <= n; i += i & -i) bit[i] = max(bit[i], val);
    }
    long long query(int idx) const {
        long long res = NEG_INF;
        for (int i = idx; i > 0; i -= i & -i) res = max(res, bit[i]);
        return res;
    }
};
struct Item {
    int day;
    int idx;
    int pos;
    int profit;
};
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N, U, D, S;
    if (!(cin >> N >> U >> D >> S)) return 0;
    vector<Item> items; items.reserve(N);
    vector<int> coords; coords.reserve(N + 1); coords.push_back(S);
    for (int i = 0; i < N; ++i) {
        int T, L, M; cin >> T >> L >> M;
        items.push_back({T, 0, L, M});
        coords.push_back(L);
    }
    sort(coords.begin(), coords.end());
    coords.erase(unique(coords.begin(), coords.end()), coords.end());
    int P = (int)coords.size();
    auto get_idx = [&](int x){ return int(lower_bound(coords.begin(), coords.end(), x) - coords.begin()) + 1; };
    for (auto &it : items) it.idx = get_idx(it.pos);
    int S_idx = get_idx(S);
    sort(items.begin(), items.end(), [](const Item& a, const Item& b){
        if (a.day != b.day) return a.day < b.day;
        return a.idx < b.idx;
    });
    const long long NEG_INF = -(1LL<<60);
    vector<long long> base(P+1, NEG_INF);
    base[S_idx] = 0;
    FenwickMax fenwLeft(P), fenwRight(P);
    fenwLeft.update(S_idx, base[S_idx] + 1LL*D*coords[S_idx-1]);
    fenwRight.update(P - S_idx + 1, base[S_idx] - 1LL*U*coords[S_idx-1]);
    int i = 0;
    while (i < N) {
        int j = i, curDay = items[i].day;
        while (j < N && items[j].day == curDay) ++j;
        int m = j - i;
        vector<int> idxs(m+1), pos(m+1), profit(m+1);
        for (int k = 1; k <= m; ++k) {
            idxs[k] = items[i + k - 1].idx;
            pos[k] = items[i + k - 1].pos;
            profit[k] = items[i + k - 1].profit;
        }
        vector<long long> H(m+1, NEG_INF);
        for (int k = 1; k <= m; ++k) {
            int idx = idxs[k];
            long long leftBest = fenwLeft.query(idx);
            long long rightBest = fenwRight.query(P - idx);
            long long cand = NEG_INF;
            if (leftBest != NEG_INF) cand = max(cand, leftBest - 1LL*D*pos[k]);
            if (rightBest != NEG_INF) cand = max(cand, rightBest + 1LL*U*pos[k]);
            H[k] = cand;
        }
        vector<long long> pref(m+1, 0);
        for (int k = 1; k <= m; ++k) pref[k] = pref[k-1] + profit[k];
        vector<long long> V1(m+1, NEG_INF);
        long long prefBest = NEG_INF;
        for (int b = 1; b <= m; ++b) {
            long long T1 = H[b] - pref[b-1] + 1LL*D*pos[b];
            prefBest = max(prefBest, T1);
            V1[b] = pref[b] - 1LL*D*pos[b] + prefBest;
        }
        vector<long long> V2(m+1, NEG_INF);
        long long suffBest = NEG_INF;
        for (int a = m; a >= 1; --a) {
            long long T2 = H[a] - 1LL*U*pos[a] + pref[a];
            suffBest = max(suffBest, T2);
            V2[a] = 1LL*U*pos[a] - pref[a-1] + suffBest;
        }
        for (int k = 1; k <= m; ++k) {
            int idx = idxs[k];
            long long newBase = max(V1[k], V2[k]);
            if (newBase > base[idx]) {
                base[idx] = newBase;
                fenwLeft.update(idx, base[idx] + 1LL*D*pos[k]);
                fenwRight.update(P - idx + 1, base[idx] - 1LL*U*pos[k]);
            }
        }
        i = j;
    }
    long long ans = 0;
    for (int p = 1; p <= P; ++p) {
        if (base[p] == NEG_INF) continue;
        long long cost = (coords[p-1] <= S) ? 1LL*D*(S - coords[p-1]) : 1LL*U*(coords[p-1] - S);
        ans = max(ans, base[p] - cost);
    }
    cout << ans << '\n';
    return 0;
}
  |