Submission #973215

# Submission time Handle Problem Language Result Execution time Memory
973215 2024-05-01T16:11:34 Z wapas Salesman (IOI09_salesman) C++17
80 / 100
346 ms 32940 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;
        }
        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);
            cacheD[j] += 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);
            cacheU[j] += 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 << 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 7 ms 20760 KB Output is correct
2 Correct 8 ms 20760 KB Output is correct
3 Correct 10 ms 20760 KB Output is correct
4 Correct 9 ms 20756 KB Output is correct
5 Correct 10 ms 20696 KB Output is correct
6 Correct 21 ms 21136 KB Output is correct
7 Correct 45 ms 21928 KB Output is correct
8 Correct 75 ms 22912 KB Output is correct
9 Correct 105 ms 26224 KB Output is correct
10 Incorrect 206 ms 29308 KB Output isn't correct
11 Correct 214 ms 28080 KB Output is correct
12 Incorrect 266 ms 31148 KB Output isn't correct
13 Correct 290 ms 30956 KB Output is correct
14 Correct 346 ms 32940 KB Output is correct
15 Correct 339 ms 32532 KB Output is correct
16 Correct 328 ms 32424 KB Output is correct
17 Correct 7 ms 20756 KB Output is correct
18 Correct 8 ms 20760 KB Output is correct
19 Correct 7 ms 20624 KB Output is correct
20 Correct 8 ms 20760 KB Output is correct
21 Correct 8 ms 20760 KB Output is correct
22 Correct 10 ms 20920 KB Output is correct
23 Correct 10 ms 20692 KB Output is correct
24 Correct 10 ms 20696 KB Output is correct
25 Correct 67 ms 23132 KB Output is correct
26 Correct 126 ms 25464 KB Output is correct
27 Correct 233 ms 30632 KB Output is correct
28 Correct 206 ms 30124 KB Output is correct
29 Correct 311 ms 32684 KB Output is correct
30 Correct 303 ms 32368 KB Output is correct