Submission #922840

#TimeUsernameProblemLanguageResultExecution timeMemory
922840thangdz2k7Split the sequence (APIO14_sequence)C++17
100 / 100
535 ms83636 KiB
#include <bits/stdc++.h>
#define ll long long
#define line pair <ll, ll>
#define Point pair <double, double>
#define A first
#define B second
#define pb push_back

using namespace std;

const int N = 1e5 + 5;
const ll inf = 1e18;

int n, k, t;
int a[N], best[205][N];
ll dp[2][N], pre[N];

vector <int> idx;

Point giao(line l1, line l2){
    Point ans;
    double del = double (l1.A) - double(l2.A);
    ans.A = double (l2.B - l1.B) / del;
    ans.B = double (ans.A) + double(l1.B) / double(l1.A);
    return ans;
}

void add(int id){
    if (idx.empty()){
        idx.pb(id);
        return;
    }
    if (pre[id] == pre[idx.back()]) return;

    while (true){
        int sz = idx.size();
        if (sz <= 1) break;
        int id2 = idx[sz - 1];
        int id3 = idx[sz - 2];
        line l2 = line(pre[id2], dp[1 ^ t][id2] - pre[id2] * pre[id2]);
        line l3 = line(pre[id3], dp[1 ^ t][id3] - pre[id3] * pre[id3]);
        line p = line(pre[id], dp[1 ^ t][id] - pre[id] * pre[id]);
        Point k = giao(p, l3);
        if (k.A / double(p.A) > (k.B - double(l2.B) / double(p.A)) / double(l2.A)) break;
        idx.pop_back();

    }
    idx.pb(id);

}

int get(int &cur, int i){
    int sz = idx.size();
    cur = min(cur, sz - 1);
    int id = idx[cur];
    line p = line(pre[id], dp[1 ^ t][id] - pre[id] * pre[id]);
    dp[t][i] = p.A * pre[i] + p.B;
    while (cur < sz - 1){
        id = idx[cur + 1];
        p = line(pre[id], dp[1 ^ t][id] - pre[id] * pre[id]);
        ll val = p.A * pre[i] + p.B;
        if (dp[t][i] < val){
            dp[t][i] = val;
            ++ cur;
        }
        else return idx[cur];
    }
    return idx[cur];
}

void solve(){
    cin >> n >> k;
    for (int i = 1; i <= n; ++ i){
        cin >> a[i];
        pre[i] = pre[i - 1] + a[i];
    }

    for (int loops = 1; loops <= k; ++ loops){
        idx.clear();
        t = loops & 1;
        int cur = 0;
        for (int i = 1; i <= n; ++ i){
            if (i == loops){
                add(i);
                best[loops][i] = i;
            }
            if (i > loops){
                dp[t][i] = inf;
                best[loops][i] = get(cur, i);
                add(i);
                //cout << loops << ' ' << i << ' ' << dp[t][i] << endl;
            }
        }
    }

    //cout << inf * inf;

    ll ans = dp[k & 1][n];
    cout << ans << '\n';
    int cur = n;
    for (int i = k; i >= 1; -- i){
        cur = best[i][cur];
        cout << cur << ' ';
    }
}

signed main(){
    //freopen("split.inp", "r", stdin);
    //freopen("split.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    solve();
    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...