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;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pl;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tt;
#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())
ll divi (ll a, ll b) {
return a / b + ((a ^ b) < 0 && a % b);
}
struct line {
ll slope, c; int id;
line (ll u = 0, ll v = 0, int z = 0) : slope(u), c(v), id(z) {}
ll calc (ll x) { return slope * x + c; }
friend ll isect (line a, line b) {
return divi(a.c - b.c, b.slope - a.slope);
}
};
struct CHT {
deque<line> hull;
void add (line cur) {
while (hull.size() >= 2 && isect(hull[hull.size() - 2], hull.back()) > isect(hull.back(), cur))
hull.pop_back();
hull.push_back(cur);
}
pair<ll,int> query (ll x) {
while (hull.size() >= 2 && x > isect(hull[0], hull[1]))
hull.pop_front();
return make_pair(hull.front().calc(x), hull.front().id);
}
};
const int mn = 1e5 + 5;
ll dp[2][mn], pre[mn];
int trace[202][mn];
void track (int k, int i, vector<int> &cuts, vector<pl> &vec) {
if (k == 0) {
cuts.push_back(vec[i].second);
return;
}
track(k - 1, trace[k][i], cuts, vec);
cuts.push_back(vec[i].second);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n, split, cnt = 0; cin >> n >> split;
vector<pl> vec(1);
queue<int> zero;
for (int i = 1; i <= n; i++) {
int a; cin >> a;
if (a) {
vec.push_back(make_pair(a, i));
cnt++;
}
else zero.push(i);
}
for (int i = 1; i <= cnt; i++)
pre[i] = pre[i - 1] + vec[i].first;
int use = min(split, cnt - 1);
for (int k = 1; k <= use; k++) {
int t = k & 1; CHT helper;
for (int i = 1; i <= k; i++)
helper.add(line(pre[i], dp[t ^ 1][i] - pre[i] * pre[i], i));
for (int i = k + 1; i <= cnt; i++) {
tie(dp[t][i], trace[k][i]) = helper.query(pre[i]);
helper.add(line(pre[i], dp[t ^ 1][i] - pre[i] * pre[i], i));
}
}
cout << dp[use & 1][cnt] << "\n";
vector<int> cuts;
track(min(split, cnt - 1), cnt, cuts, vec);
cuts.pop_back();
while (cuts.size() < split) {
cuts.push_back(zero.front());
zero.pop();
}
for (int u : cuts) cout << u << " ";
return 0;
}
Compilation message (stderr)
sequence.cpp: In function 'int main()':
sequence.cpp:96:24: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
96 | while (cuts.size() < split) {
| ~~~~~~~~~~~~^~~~~~~
# | 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... |