This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
const int64_t INF = 1e18;
template<typename T>
struct LiChaoTree{
static const T identity = 0;
struct Line{
T m, c;
Line(){
m = 0;
c = identity;
}
Line(T m, T c) : m(m), c(c) {}
T val(T x){
return m*x + c;
}
};
struct Node{
Node *lc, *rc;
Line line;
int idx;
Node() : lc(0), rc(0) {}
};
deque<Node> buffer;
Node* new_node(){
buffer.emplace_back();
return &buffer.back();
}
Node *root;
T L, R;
void init(T L, T R){
this->L = L;
this->R = R;
root = new_node();
}
void insert(Node* &node, T l, T r, Line line, int idx){
if(!node){
node = new_node();
node->line = line;
node->idx = idx;
return;
}
if(r - l == 1)
return;
T mid = (l + r) >> 1;
if(line.val(mid) > node->line.val(mid)){
swap(line, node->line);
swap(idx, node->idx);
}
if(line.val(l) > node->line.val(l)) insert(node->lc, l, mid, line, idx);
else insert(node->rc, mid, r, line, idx);
}
pair<T, int> query(Node* &node, T l, T r, T x){
if(!node)
return {identity, 0};
T mid = (l + r) >> 1;
pair<T, int> res = {node->line.val(x), node->idx};
if(r - l == 1)
return res;
if(x < mid) return max(res, query(node->lc, l, mid, x));
else return max(res, query(node->rc, mid, r, x));
}
void clear(){
buffer.clear();
}
void insert(T m, T c, int idx) { insert(root, L, R, Line(m, c), idx); }
pair<T, int> query(T x) { return query(root, L, R, x); }
};
int32_t main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, K;
cin >> N >> K;
vector<int64_t> pref(N+1);
for(int i = 1; i <= N; i++){
cin >> pref[i];
pref[i] += pref[i-1];
}
LiChaoTree<int64_t> dp[2];
vector<vector<int>> par(K+1, vector<int>(N+1, -1));
for(int i = 0; i < 2; i++)
dp[i].init(0, 1e9);
int64_t temp = 0;
pair<int64_t, int> ans = {0, 0};
for(int i = 1; i <= K; i++){
int t = (i-1)&1, z = i&1;
dp[z].clear();
dp[z].init(0, 1e9);
for(int j = 1; j < N; j++){
pair<int64_t, int> q = dp[t].query(pref[N] - pref[j]);
temp = q.first + pref[j]*(pref[N] - pref[j]);
int p = q.second;
dp[z].insert(-pref[j], temp, j);
ans = max(ans, {temp, j});
par[i][j] = p;
}
}
cout << ans.first << '\n';
int nxt = ans.second;
for(int i = K; i > 0; --i){
cout << nxt << ' ';
nxt = par[i][nxt];
}
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... |