Submission #1270711

#TimeUsernameProblemLanguageResultExecution timeMemory
1270711_callmelucianFeast (NOI19_feast)C++17
100 / 100
641 ms42480 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using pl = pair<ll,ll>;
using pii = pair<int,int>;
using tpl = tuple<int,int,int>;

#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())

const ll INF = 1e18;

vector<ll> minkowskiSum (const vector<ll> &a, const vector<ll> &b) { // slope trick
    assert(a.size() && b.size());
    vector<ll> deltaA(a.size() - 1), deltaB(b.size() - 1);
    for (int i = 0; i + 1 < a.size(); i++) deltaA[i] = a[i + 1] - a[i];
    for (int i = 0; i + 1 < b.size(); i++) deltaB[i] = b[i + 1] - b[i];

    vector<ll> slope(deltaA.size() + deltaB.size());
    merge(all(deltaA), all(deltaB), slope.begin(), greater<ll>());

    vector<ll> ans(1, a[0] + b[0]);
    for (ll u : slope) ans.push_back(ans.back() + u);
    return ans;
}

vector<ll> shiftIndex (const vector<ll> &a) {
    assert(a.size());
    vector<ll> ans(a.size() - 1);
    for (int i = 1; i < a.size(); i++) ans[i - 1] = a[i];
    return ans;
}

vector<ll> mergeChain (vector<ll> a, vector<ll> b) {
    while (a.size() < b.size()) a.push_back(-INF);
    while (a.size() > b.size()) b.push_back(-INF);

    vector<ll> ans(a.size());
    for (int i = 0; i < ans.size(); i++) ans[i] = max(a[i], b[i]);
    return ans;
}

using dncItem = array<array<vector<ll>, 2>, 2>;
const int mn = 3e5 + 5;

int a[mn], n, k;

dncItem solve (int l, int r) {
    if (l == r) {
        dncItem cur;
        cur[0][0] = {0, max(0, a[l])};
        cur[0][1] = cur[1][0] = cur[1][1] = {-INF, a[l]};
        return cur;
    }

    // divide
    int mid = (l + r) >> 1;
    dncItem leftSolve = solve(l, mid), rightSolve = solve(mid + 1, r);

    // merge
    dncItem cur;
    for (int t1 = 0; t1 < 2; t1++) {
        for (int t2 = 0; t2 < 2; t2++) {
            cur[t1][t2] = mergeChain(minkowskiSum(leftSolve[t1][0], rightSolve[0][t2]),
                                     shiftIndex(minkowskiSum(leftSolve[t1][1], rightSolve[1][t2])));
        }
    }
    return cur;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> k;
    for (int i = 1; i <= n; i++) cin >> a[i];

    dncItem res = solve(1, n);
    cout << res[0][0][k] << "\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...