Submission #321283

#TimeUsernameProblemLanguageResultExecution timeMemory
321283shart23Split the sequence (APIO14_sequence)C++14
71 / 100
249 ms131076 KiB
#include <bits/stdc++.h> #define short int #define int long long //#define double long double #define all(x) x.begin(), x.end() using namespace std; struct Line { int k; int b; Line(int k_, int b_) : k(k_), b(b_) {} }; struct CHT { const int INF = (int) 1e18; vector<Line> lns; vector<double> pts = {(double) -INF}; vector<int> inds; double inter(Line ln1, Line ln2) { double x = (ln2.b - ln1.b) / (double) (ln1.k - ln2.k); return x; } void add(int k, int b, int ind) { Line nln(k, b); while ((int) lns.size() > 1) { if (k == lns.back().k) { if (b < lns.back().b) { return; } lns.pop_back(); inds.pop_back(); pts.pop_back(); continue; } double nx = inter(nln, lns[(int) lns.size() - 2]); if (nx < pts.back()) { lns.pop_back(); inds.pop_back(); pts.pop_back(); } else { break; } } if (!lns.empty() && lns.back().k == k) { if (b < lns.back().b) { return; } lns.pop_back(); inds.pop_back(); lns.push_back(nln); inds.push_back(ind); } else { lns.push_back(nln); inds.push_back(ind); if ((int) lns.size() > 1) { pts.push_back(inter(lns.back(), lns[(int) lns.size() - 2])); } } } pair<int, int> best(int x) { int l = 0, r = pts.size(); while (r - l > 1) { int m = (l + r) / 2; if (pts[m] > x) { r = m; } else { l = m; } } return {lns[l].k * x + lns[l].b, inds[l]}; } }; signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int n, k; cin >> n >> k; vector<int> a(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i]; a[i] += a[i - 1]; } vector<vector<short>> prev(k + 1, vector<short>(n + 1, -1)); vector<int> dp(n + 1); for (int j = 1; j <= k; j++) { CHT cht; cht.add(a[j - 1], dp[j - 1] - a[j - 1] * a[j - 1], j - 1); vector<int> ndp(n + 1); for (int i = j; i <= n; i++) { auto res = cht.best(a[i]); ndp[i] = res.first; prev[j][i] = res.second; cht.add(a[i], dp[i] - a[i] * a[i], i); } swap(dp, ndp); } int ans = dp[n]; cout << ans << '\n'; vector<short> path; int now = n; for (int i = k; i >= 1; i--) { now = prev[i][now]; path.push_back(now); } reverse(all(path)); for (int el : path) { cout << el << ' '; } cout << '\n'; } /* 7 3 4 1 3 4 0 2 3 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...