QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#679152#9529. Farm Managementucup-team4435#RE 1ms3844kbC++206.4kb2024-10-26 17:00:402024-10-26 17:00:41

Judging History

你现在查看的是最新测评结果

  • [2024-10-26 17:00:41]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:3844kb
  • [2024-10-26 17:00:40]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

#define all(a) begin(a), end(a)
#define len(a) int((a).size())

/*
 * Node must have default constructor.
 * Node must have static function merge.
 * Node must have .push and .clear_after_push methods.
*/

template<typename node>
class segtree {
private:
    void build(int v, int vl, int vr) {
        if (vr - vl <= 1)
            return;
 
        int vm = (vl + vr) >> 1;
        build(v << 1, vl, vm);
        build(v << 1 | 1, vm, vr);
        tree[v] = node::merge(tree[v << 1], tree[v << 1 | 1]);
    }

    template<typename T>
    void build(int v, int vl, int vr, const std::vector<T> &arr) {
        if (vl == vr)
            return;
 
        if (vr - vl == 1) {
            tree[v] = node(arr[vl]);
            return;
        }
 
        int vm = (vl + vr) >> 1;
        build(v << 1, vl, vm, arr);
        build(v << 1 | 1, vm, vr, arr);
        tree[v] = node::merge(tree[v << 1], tree[v << 1 | 1]);
    }

    template<typename... Args>
    void _update(int v, int vl, int vr, int l, int r, Args&&... args) {
        if (r <= vl || vr <= l)
            return;
 
        if (l <= vl && vr <= r) {
            tree[v].apply(std::forward<Args>(args)..., vl, vr);
            return;
        }
 
        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vm);
        tree[v].push(tree[v << 1 | 1], vm, vr);
        tree[v].clear_after_push();
 
        _update(v << 1, vl, vm, l, r, std::forward<Args>(args)...);
        _update(v << 1 | 1, vm, vr, l, r, std::forward<Args>(args)...);
        tree[v] = node::merge(tree[v << 1], tree[v << 1 | 1]);
    }

    node _query(int v, int vl, int vr, int l, int r) {
        if (l <= vl && vr <= r)
            return tree[v];
 
        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vm);
        tree[v].push(tree[v << 1 | 1], vm, vr);
        tree[v].clear_after_push();
 
        if (r <= vm)
            return _query(v << 1, vl, vm, l, r);
 
        if (vm <= l)
            return _query(v << 1 | 1, vm, vr, l, r);
 
        return node::merge(_query(v << 1, vl, vm, l, r), _query(v << 1 | 1, vm, vr, l, r));
    }

    template<typename T>
    int _find_first(int v, int vl, int vr, int from, const T &checker) {
        if (vr <= from)
            return n;

        if (from <= vl && !checker(tree[v], vl, vr))
            return n;

        if (vr - vl == 1)
            return vl;

        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vm);
        tree[v].push(tree[v << 1 | 1], vm, vr);
        tree[v].clear_after_push();

        int res = _find_first(v << 1, vl, vm, from, checker);
        return res == n ? _find_first(v << 1 | 1, vm, vr, from, checker) : res;
    }

    template<typename T>
    int _find_last(int v, int vl, int vr, int from, const T &checker) {
        if (from <= vl)
            return -1;

        if (vr <= from && !checker(tree[v], vl, vr))
            return -1;

        if (vr - vl == 1)
            return vl;

        int vm = (vl + vr) >> 1;
        tree[v].push(tree[v << 1], vl, vm);
        tree[v].push(tree[v << 1 | 1], vm, vr);
        tree[v].clear_after_push();

        int res = _find_last(v << 1 | 1, vm, vr, from, checker);
        return res == -1 ? _find_last(v << 1, vl, vm, from, checker) : res;
    }

public:
    int n;
    std::vector<node> tree;

    segtree(int n) : n(n), tree(4 * n, node()) {
        build(1, 0, n);
    }

    template<typename T>
    segtree(const std::vector<T> &arr) : n(arr.size()), tree(4 * n) {
        build(1, 0, n, arr);
    }
 
    int size() const {
        return n;
    }
 
    template<typename... Args>
    void update(int l, int r, Args&&... args) {
        if (r <= l)
            return;

        _update(1, 0, n, l, r, std::forward<Args>(args)...);
    }
 
    node query(int l, int r) {
        assert(std::max(0, l) < std::min(n, r)); // or return node() in this case
        return _query(1, 0, n, l, r);
    }

    // Trying to find first true on the interval [from, n).
    // Returns n if not found.
    template<typename T>
    int find_first(int from, const T &checker) {
        return _find_first(1, 0, n, from, checker);
    }

    // Trying to find last true on the interval [0, from).
    // Returns -1 if not found.
    template<typename T>
    int find_last(int from, const T &checker) {
        return _find_last(1, 0, n, from, checker);
    }
};

struct node {
    ll cost = 0, lens = 0;

    void apply(ll x, ll y, int /* vl */, int /* vr */) {
        cost = x;
        lens = y;
    }

    void push(node /* &child */, int /* cl */, int /* cr */) {}
    void clear_after_push() {}

    static node merge(const node &left, const node &right) {
        node res;
        res.cost = left.cost + right.cost;
        res.lens = left.lens + right.lens;
        return res;
    }
};

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    vector<array<ll, 3>> a(n);
    ll sum_l = 0, cur_cost = 0;
    for (auto &[w, l, r] : a) {
        cin >> w >> l >> r;
        sum_l += l;
        cur_cost += w * l;
    }

    sort(all(a));
    reverse(all(a));

    segtree<node> tree(n);
    for (int i = 0; i < n; i++) {
        ll cur_len = a[i][2] - a[i][1];
        tree.update(i, i + 1, cur_len * a[i][0], cur_len);
    }

    auto solve = [&]() {
        assert(sum_l >= 0);
        ll need = m - sum_l;
        assert(need >= 0);

        int pos = tree.find_first(0, [&](const node &nd, int, int) {
            if (nd.lens > need) {
                return true;
            }
            need -= nd.lens;
            return false;
        });
        assert(pos < n);

        ll res = cur_cost;
        if (pos > 0) {
            res += tree.query(0, pos).cost;
        }
        res += need * a[pos][0];

        return res;
    };

    ll ans = solve();
    for (int i = 0; i < n; i++) {
        ll cur_len = a[i][2] - a[i][1];
        sum_l -= a[i][1];
        cur_cost -= a[i][1] * a[i][0];
        tree.update(i, i + 1, m * a[i][0], m);

        ans = max(ans, solve());

        tree.update(i, i + 1, cur_len * a[i][0], cur_len);
        cur_cost += a[i][1] * a[i][0];
        sum_l += a[i][1];
    }
    cout << ans << '\n';
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3844kb

input:

5 17
2 3 4
6 1 5
8 2 4
4 3 3
7 5 5

output:

109

result:

ok single line: '109'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3592kb

input:

12 62
503792 9 10
607358 1 3
600501 10 10
33249 4 4
774438 6 6
197692 3 6
495807 8 8
790225 5 9
77272 3 8
494819 4 9
894779 3 9
306279 5 6

output:

35204500

result:

ok single line: '35204500'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3560kb

input:

15 32
835418 2 3
178262 1 3
527643 2 2
519710 1 1
774544 3 3
82312 1 1
808199 1 1
809396 1 3
255882 1 3
80467 1 3
874973 1 3
813965 1 2
198275 1 2
152356 1 3
802055 1 1

output:

22000255

result:

ok single line: '22000255'

Test #4:

score: 0
Accepted
time: 0ms
memory: 3588kb

input:

13 20
526447 1 1
807398 2 2
4167 1 2
944031 2 2
830685 2 2
394251 1 2
505011 1 2
968848 1 1
58170 1 3
32504 1 1
792273 3 3
196120 1 2
714507 1 1

output:

12878768

result:

ok single line: '12878768'

Test #5:

score: -100
Runtime Error

input:

13 32
582584 1 3
335440 3 3
971984 1 2
864169 1 2
528515 1 1
382399 1 2
459855 1 2
406909 2 3
66780 2 3
885118 3 3
434844 1 2
93331 1 3
502509 1 3

output:


result: