Submission #1138529

#TimeUsernameProblemLanguageResultExecution timeMemory
1138529anmattroiSplit the sequence (APIO14_sequence)C++17
100 / 100
1858 ms84112 KiB
#include <bits/stdc++.h>
#define maxn 100005
#define fi first
#define se second
using namespace std;

struct line {
    int a; int64_t b;
    line() {}
    line(int _a, int64_t _b) : a(_a), b(_b) {}

    long double intersectX(const line &other) const {
        return (long double) (b-other.b) / (other.a-a);
    }
};

int64_t f(line x, int y) {
    return 1LL * x.a * y + x.b;
}

int n, k;
int a[maxn], s[maxn];
int64_t dp[maxn][2];
int p[maxn][205];

int main() {
//    if (fopen("check.inp", "r")) {
//        freopen("check.inp", "r", stdin);
//        freopen("check.out", "w", stdout);
//    }
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        s[i] = s[i-1] + a[i];
    }
    ++k;
    for (int i = 0; i <= n; i++) for (int j = 0; j <= 1; j++) dp[i][j] = LLONG_MIN;
    dp[0][0] = 0;

    for (int c = 1; c <= k; c++) {
        int u = c&1, v = 1-u;
        deque<pair<line, int> > dq;
        dq.push_back({{0, 0}, 0});
        for (int i = 1; i <= n; i++) {
            while (dq.size() >= 2 && f(dq[0].fi, s[i]) <= f(dq[1].fi, s[i])) dq.pop_front();
            dp[i][u] = f(dq[0].fi, s[i]);
            p[i][c] = dq[0].se;
            if (dp[i][v] == LLONG_MIN) continue;
            line cur = line(s[i], dp[i][v] - 1LL * s[i] * s[i]);
            if (dq.back().fi.a == cur.a) {
                if (dq.back().fi.b > cur.b) continue;
                dq.pop_back();
            }
            while (dq.size() >= 2 && dq.back().fi.intersectX(cur) <= dq.back().fi.intersectX(dq[dq.size()-2].fi)) dq.pop_back();
            dq.push_back({cur, i});
        }
    }
    cout << dp[n][k&1] << "\n";

    int oz = p[n][k];
    vector<int> Ans;
    for (int i = k-1; i >= 1; i--) {
        Ans.emplace_back(oz);
//        assert(oz);
        oz = p[oz][i];
    }
    reverse(Ans.begin(), Ans.end());
    for (int i : Ans) cout << i << ' ';
}
#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...