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 <cstdio>
#include <vector>
#include <algorithm>
#include <stack>
#include <tuple>
#define M(x) lines[x].first
#define C(x) lines[x].second
#define bad(x,y,z) ((C(y)-C(x))*(M(x)-M(z)) >= (C(z)-C(x))*(M(x)-M(y)))
using namespace std;
int a[100005];
long long dp[100005][2]; // End with i, having j parts;
int qs[100005];
int par[100005][256];
vector<pair<long long,long long> > lines;
vector<int> idx;
inline void add(int i,long long m, long long c){
lines.emplace_back(m,c);
idx.push_back(i);
while(lines.size() >= 3 && bad(lines.size()-3, lines.size()-2, lines.size()-1)){
lines.pop_back();
lines.pop_back();
lines.emplace_back(m,c);
idx.pop_back();
idx.pop_back();
idx.push_back(i);
}
}
int ptr;
inline pair<int,long long> query(long long x){
if(ptr >= lines.size()) ptr = lines.size()-1;
while(ptr < lines.size()-1 && M(ptr+1)*x + C(ptr+1) > M(ptr)*x + C(ptr)) ptr++;
return make_pair(idx[ptr],M(ptr)*x + C(ptr));
}
inline int fastscan(){
int x = 0;
int c = getchar();
while(c < 48 || c >= 58) c = getchar();
while(c >= 48 && c < 58){
x *= 10;
x += c-48;
c = getchar();
}
return x;
}
int main(){
int n,k;
n = fastscan();
k = fastscan();
k++;
add(0,0,0);
for(int i = 1; i <= n; i++){
a[i] = fastscan();
qs[i] = qs[i-1] + a[i];
dp[i][0] = -1e16;
}
for(int j = 1; j <= k; j++){
for(int i = max(1,j-1); i <= n; i++){
if(i >= j)
tie(par[i][j],dp[i][j % 2]) = query(qs[i]);
add(i,(long long)qs[i], dp[i][(j+1) % 2] - (long long)qs[i]*(long long)qs[i]);
}
lines.clear();
idx.clear();
ptr = 0;
}
printf("%lld\n",dp[n][k % 2]);
int x = n;
stack<int> stk;
for(int j = k; j > 1; j--){
x = par[x][j];
stk.push(x);
}
while(!stk.empty()){
printf("%d ",stk.top());
stk.pop();
}
}
Compilation message (stderr)
sequence.cpp: In function 'std::pair<int, long long int> query(long long int)':
sequence.cpp:30:9: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if(ptr >= lines.size()) ptr = lines.size()-1;
~~~~^~~~~~~~~~~~~~~
sequence.cpp:31:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while(ptr < lines.size()-1 && M(ptr+1)*x + C(ptr+1) > M(ptr)*x + C(ptr)) ptr++;
~~~~^~~~~~~~~~~~~~~~
# | 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... |