Submission #1320141

#TimeUsernameProblemLanguageResultExecution timeMemory
1320141fatelessSplit the sequence (APIO14_sequence)C++20
50 / 100
23 ms12616 KiB
// #pragma GCC optimize("Ofast,unroll-loops")
#include <bits/stdc++.h>
using namespace std;

#define now chrono::steady_clock::now().time_since_epoch().count()
#define speedup cin.tie(0)->sync_with_stdio(0)
#define bitcount(x) __builtin_popcountll(x)
#define lla(x) x.rbegin(), x.rend()
#define all(x) x.begin(), x.end()
#define Tp template <class T>
#define int long long
#define pb push_back
#define vc vector
#define arr array

const int inf = 1e18, N = 1e3 + 10, K = 250;
Tp bool chmin (T &a, T b) {if (a > b) {a = b; return 1;} return 0;}
Tp bool chmax (T &a, T b) {if (a < b) {a = b; return 1;} return 0;}
struct line {
    int m, b, id;
    line (int _m = 0, int _b = 0, int _id = 0) : m(_m), b(_b), id(_id) {}
    int get (int x) {return (m * x + b);} 
};
struct segtree {
    struct node {
        line m;
        node *l, *r;
        node (line _m) : m(_m), l(NULL), r(NULL) {}
    };

    int lb, rb;
    node* root;
    segtree (int _lb, int _rb) : lb(_lb), rb(_rb), root(NULL) {}

    void add (node *&x, line nw, int lx, int rx) {
        if (!x) {x = new node(nw); return;}

        int mid = (lx + rx) >> 1;
        bool l = nw.get(lx) > x->m.get(lx);
        bool m = nw.get(mid) > x->m.get(mid);

        if (m) swap(nw, x->m);
        if (rx - lx == 1) return;
        (l != m)? add (x->l, nw, lx, mid) : add (x->r, nw, mid, rx);
    } void add (line nw) {add(root, nw, lb, rb);}

    pair<int, int> get (node *x, int lx, int rx, int id) {
        if (!x) return {-inf, 0};
        pair<int, int> res = {x->m.get(id), x->m.id};
        if (rx - lx == 1) return res;
        int mid = (lx + rx) >> 1;
        if (id < mid) return max (res, get (x->l, lx, mid, id));
        else return max (res, get (x->r, mid, rx, id));
    } pair<int, int> get (int id) {return get(root, lb, rb, id);}
};

static int a[N], pf[N], dp[K][N], opt[K][N];
inline void solve () {
    int n, kx;
    cin >> n >> kx;
    pf[0] = a[0] = 0;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) pf[i] = pf[i - 1] + a[i];

    memset(dp, -1, sizeof(dp));
    memset(opt, 0, sizeof(opt));
    for (int i = 1; i <= n; i++) dp[0][i] = 0;
    for (int i = 1; i <= kx; i++) {
        segtree st (0, pf[n] + 100);
        // cout << i << " :\n";
        st.add(line(pf[i], dp[i - 1][i] - (pf[i] * pf[i]), i));
        for (int j = i + 1; j <= n; j++) {
            auto [val, id] = st.get(pf[j]);
            tie(dp[i][j], opt[i][j]) = {val, id};
            // cout << dp[i][j] << ' ' << opt[i][j] << '\n';
            st.add(line(pf[j], dp[i - 1][j] - (pf[j] * pf[j]), j));
        }
        // cout << "\n";
    }
    
    int x = n;
    vc<int> ans;
    for (int i = kx; i >= 1; i--) {
        x = opt[i][x];
        ans.pb(x);
    }

    reverse(all(ans));
    cout << dp[kx][n] << '\n';
    for (int &x : ans) cout << x << ' ';
}

signed main() {
    speedup;
    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...