Submission #1300000

#TimeUsernameProblemLanguageResultExecution timeMemory
1300000khoavn2008Feast (NOI19_feast)C++17
22 / 100
71 ms87008 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll NEG = -(ll)9e18;

struct Node {
    int l, r;
    ll sum;
    ll pref; int prefL, prefR;
    ll suf;  int sufL,  sufR;
    ll best; int bestL, bestR;
    bool lazy; // assign to NEG
    Node() {
        l = r = 0;
        sum = pref = suf = best = NEG;
        prefL = prefR = sufL = sufR = bestL = bestR = -1;
        lazy = false;
    }
};

int N, K;
vector<ll> a;
vector<Node> seg;

Node make_leaf(int idx, ll val) {
    Node nd;
    nd.l = nd.r = idx;
    nd.sum = val;
    nd.pref = val; nd.prefL = nd.prefR = idx;
    nd.suf  = val; nd.sufL  = nd.sufR  = idx;
    nd.best = val; nd.bestL = nd.bestR = idx;
    nd.lazy = false;
    return nd;
}

Node combine(const Node &L, const Node &R) {
    if (L.l==0) return R;
    if (R.l==0) return L;
    Node res;
    res.l = L.l; res.r = R.r;
    res.sum = L.sum + R.sum;

    // prefix
    ll leftPref = L.pref;
    ll crossPref = (L.sum==NEG || R.pref==NEG) ? NEG : L.sum + R.pref;
    if (leftPref >= crossPref) {
        res.pref = leftPref;
        res.prefL = L.prefL; res.prefR = L.prefR;
    } else {
        res.pref = crossPref;
        res.prefL = L.l; res.prefR = R.prefR;
    }

    // suffix
    ll rightSuf = R.suf;
    ll crossSuf = (R.sum==NEG || L.suf==NEG) ? NEG : R.sum + L.suf;
    if (rightSuf >= crossSuf) {
        res.suf = rightSuf;
        res.sufL = R.sufL; res.sufR = R.sufR;
    } else {
        res.suf = crossSuf;
        res.sufL = L.sufL; res.sufR = R.r;
    }

    // best
    res.best = L.best; res.bestL = L.bestL; res.bestR = L.bestR;
    if (R.best > res.best) {
        res.best = R.best; res.bestL = R.bestL; res.bestR = R.bestR;
    }
    if (L.suf != NEG && R.pref != NEG) {
        ll cross = L.suf + R.pref;
        if (cross > res.best) {
            res.best = cross;
            res.bestL = L.sufL;
            res.bestR = R.prefR;
        }
    }
    res.lazy = false;
    return res;
}

void build(int p, int l, int r) {
    if ((int)seg.size() <= p) seg.resize(p+1);
    seg[p].l = l; seg[p].r = r;
    seg[p].lazy = false;
    if (l == r) {
        seg[p] = make_leaf(l, a[l]);
        return;
    }
    int m = (l + r) >> 1;
    build(p<<1, l, m);
    build(p<<1|1, m+1, r);
    seg[p] = combine(seg[p<<1], seg[p<<1|1]);
}

void apply_assign_neg(int p) {
    seg[p].sum = NEG * (seg[p].r - seg[p].l + 1);
    seg[p].pref = seg[p].suf = seg[p].best = NEG;
    seg[p].prefL = seg[p].prefR = seg[p].sufL = seg[p].sufR = seg[p].bestL = seg[p].bestR = -1;
    seg[p].lazy = true;
}

void push(int p) {
    if (!seg[p].lazy || seg[p].l == seg[p].r) return;
    apply_assign_neg(p<<1);
    apply_assign_neg(p<<1|1);
    seg[p].lazy = false;
}

void update_range_assign_neg(int p, int l, int r) {
    if (r < seg[p].l || seg[p].r < l) return;
    if (l <= seg[p].l && seg[p].r <= r) {
        apply_assign_neg(p);
        return;
    }
    push(p);
    update_range_assign_neg(p<<1, l, r);  
    update_range_assign_neg(p<<1|1, l, r);
    seg[p] = combine(seg[p<<1], seg[p<<1|1]);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    if (!(cin >> N >> K)) return 0;
    a.assign(N+1, 0);
    for (int i = 1; i <= N; ++i) cin >> a[i];
    seg.assign(4*(N+5), Node());
    build(1,1,N);

    ll ans = 0;
    for (int t = 0; t < K; ++t) {
        ll best = seg[1].best;
        if (best <= 0) break;
        int L = seg[1].bestL;
        int R = seg[1].bestR;
        ans += best;
        update_range_assign_neg(1, L, R);
    }
    cout << ans << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...