// #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, lim = 1e10;
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 (mid) swap(nw, x->m);
if (rx - lx == 1) return;
if (l != m) add (x->l, nw, lx, mid);
else 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, lim);
st.add(line(pf[i], -(pf[i] * pf[i]) + dp[i - 1][i], i));
for (int j = 2; j <= n; j++) {
auto [val, id] = st.get(pf[j]);
tie(dp[i][j], opt[i][j]) = {val, id};
st.add(line(pf[j], -(pf[j] * pf[j]) + dp[i - 1][j], j));
}
}
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 time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |