Submission #321469

#TimeUsernameProblemLanguageResultExecution timeMemory
321469shart23Split the sequence (APIO14_sequence)C++14
71 / 100
971 ms131072 KiB
#include <bits/stdc++.h> #define short int #define int long long #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<short> inds; int ind_ = 0; 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) { while (pts[ind_] > x) { ind_--; } while (ind_ < (int) pts.size() - 1 && pts[ind_ + 1] <= x) { ind_++; } return {lns[ind_].k * x + lns[ind_].b, inds[ind_]}; } }; short par[205][100500]; 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<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; par[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 = par[i][now]; path.push_back(now); } reverse(all(path)); for (int el : path) { if (el > 0) { 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...