Submission #973217

# Submission time Handle Problem Language Result Execution time Memory
973217 2024-05-01T16:16:46 Z wapas Salesman (IOI09_salesman) C++17
100 / 100
330 ms 33108 KB
// code by wapas
#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
 
/*
  segtree code by : https://github.com/atcoder/ac-library/blob/master/atcoder/segtree.hpp
  how to use : https://github.com/atcoder/ac-library/blob/master/document_en/segtree.md
*/
#if __cplusplus < 202002L
unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}
#endif
 
int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}
 
template <class S, auto op, auto e> struct segtree {
    static_assert(is_convertible_v<decltype(op), function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(is_convertible_v<decltype(e), function<S()>>,
                  "e must work as S()");
  
  public:
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(vector<S>(n, e())) {}
    explicit segtree(const vector<S>& v) : _n(int(v.size())) {
        size = (int) bit_ceil((unsigned int)(_n));
        log = countr_zero((unsigned int)size);
        d = vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }
 
    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }
 
    S get(int p) const {
        assert(0 <= p && p < _n);
        return d[p + size];
    }
 
    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;
 
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }
 
    S all_prod() const { return d[1]; }
 
    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }
 
    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }
 
  private:
    int _n, size, log;
    vector<S> d;
 
    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
 
struct market {
    ll date, pos, profit;
    bool operator < (const market &o) const {
        if (date == o.date) return pos < o.pos;
        return date < o.date;
    } 
};
 
ll op(ll a, ll b) {
    return max(a, b);
}
 
const ll inf = -1e18;
ll e() {
    return inf;
}
 
#define SEG_MAX 500002
void solution(int t) {
    int N, U, D, S; cin >> N >> U >> D >> S;
    vector<market> arr;
    arr.push_back({ 0, S, 0 });
    arr.push_back({ (int) 1e8, S, 0 });
    arr.push_back({ (int) 1e9, S, 0 });
    for (int i = 0; i < N; i++) {
        ll d, p, c; cin >> d >> p >> c;
        arr.push_back({ d, p, c });
    }
    N += 3;
    ll ans = 0;
    sort(arr.begin(), arr.end());
    segtree<ll, op, e> stD(SEG_MAX), stU(SEG_MAX);
    stD.set(S, arr[0].pos * D); stU.set(S, -arr[0].pos * U);
    ll last = arr[1].date, lastIdx = 1;
    for (int i = 1; i < N; i++) {
        if (last == arr[i].date) continue;
        int M = i - lastIdx;
        vector<ll> cacheD(M, inf), cacheU(M, inf);
        for (int j = 0; j < M; j++) {
            int k = lastIdx + j;
            ll res = inf;
            res = max(res, stD.prod(0, arr[k].pos) - arr[k].pos * D);
            res = max(res, stU.prod(arr[k].pos + 1, SEG_MAX) + arr[k].pos * U);
            cacheD[j] = cacheU[j] = res + arr[k].profit;
        }
        for (int j = 0; j < M; j++) {
            int k = lastIdx + j;
            if (j != 0) cacheD[j] = max(cacheD[j], cacheD[j - 1] - (arr[k].pos - arr[k - 1].pos) * D + arr[k].profit);
        }
        for (int j = M - 1; j >= 0; j--) {
            int k = lastIdx + j;
            if (j != M - 1) cacheU[j] = max(cacheU[j], cacheU[j + 1] - (arr[k + 1].pos - arr[k].pos) * U + arr[k].profit);
        }
        for (int j = 0; j < M; j++) {
            int k = lastIdx + j;
            ll res = max(cacheD[j], cacheU[j]);
            if (i == N - 1) cout << max(0LL, res);
            stD.set(arr[k].pos, res + arr[k].pos * D);
            stU.set(arr[k].pos, res - arr[k].pos * U);
        }
        last = arr[i].date; lastIdx = i;
    }
}
 
int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    // int T; cin >> T;
    int T = 1;
    for (int t = 0; t < T; t++) {
        solution(t);
    }
}

Compilation message

salesman.cpp: In function 'void solution(int)':
salesman.cpp:167:8: warning: unused variable 'ans' [-Wunused-variable]
  167 |     ll ans = 0;
      |        ^~~
# Verdict Execution time Memory Grader output
1 Correct 8 ms 20664 KB Output is correct
2 Correct 8 ms 20760 KB Output is correct
3 Correct 7 ms 20760 KB Output is correct
4 Correct 9 ms 20760 KB Output is correct
5 Correct 10 ms 20696 KB Output is correct
6 Correct 21 ms 21136 KB Output is correct
7 Correct 42 ms 21900 KB Output is correct
8 Correct 74 ms 23084 KB Output is correct
9 Correct 103 ms 24432 KB Output is correct
10 Correct 176 ms 27764 KB Output is correct
11 Correct 218 ms 28824 KB Output is correct
12 Correct 274 ms 31148 KB Output is correct
13 Correct 330 ms 30996 KB Output is correct
14 Correct 329 ms 32804 KB Output is correct
15 Correct 310 ms 32532 KB Output is correct
16 Correct 326 ms 32424 KB Output is correct
17 Correct 7 ms 20756 KB Output is correct
18 Correct 7 ms 20760 KB Output is correct
19 Correct 8 ms 20760 KB Output is correct
20 Correct 9 ms 20760 KB Output is correct
21 Correct 9 ms 20720 KB Output is correct
22 Correct 12 ms 20952 KB Output is correct
23 Correct 11 ms 20696 KB Output is correct
24 Correct 9 ms 20928 KB Output is correct
25 Correct 67 ms 23136 KB Output is correct
26 Correct 138 ms 25480 KB Output is correct
27 Correct 207 ms 30636 KB Output is correct
28 Correct 210 ms 29104 KB Output is correct
29 Correct 292 ms 32680 KB Output is correct
30 Correct 307 ms 33108 KB Output is correct