// #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 = 1e5 + 1, K = 201;
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], 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(opt, 0, sizeof(opt));
vc<int> dp (n + 1), prev (n + 1);
for (int i = 1; i <= kx; i++) {
swap(dp, prev);
segtree st (0, pf[n] + 100);
st.add(line(pf[i], prev[i] - (pf[i] * pf[i]), i));
for (int j = i + 1; j <= n; j++) {
auto [val, id] = st.get(pf[j]);
tie(dp[j], opt[i][j]) = {val, id};
st.add(line(pf[j], prev[j] - (pf[j] * pf[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[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... |