Submission #1027086

#TimeUsernameProblemLanguageResultExecution timeMemory
1027086borisAngelovSplit the sequence (APIO14_sequence)C++17
71 / 100
287 ms131072 KiB
#include <bits/stdc++.h> using namespace std; const int maxn = 100005; const int maxk = 205; const double inf = 1e300; int n, k; long long a[maxn]; long long pref[maxn]; long long dp[maxk]; int prvState[maxn][maxk]; long long sum(int from, int to) { return pref[to] - pref[from - 1]; } struct Line { long long a; long long b; int idx; long long calc(long long x) { return a * x + b; } }; struct ConvexHullTrickMAX { vector<pair<Line, double>> upperEnvelope; double cross(const Line& l1, const Line& l2) { return (1.0 * (l1.b - l2.b)) / (1.0 * (l2.a - l1.a)); } bool toRemove(const Line& newLine, pair<Line, double> last) { if (newLine.a == last.first.a) { return newLine.b >= last.first.b; } return cross(newLine, last.first) <= last.second; } void addLine(Line newLine) { while (upperEnvelope.size() >= 1 && toRemove(newLine, upperEnvelope.back()) == true) { upperEnvelope.pop_back(); } if (upperEnvelope.empty()) { upperEnvelope.push_back({newLine, -inf}); } else { upperEnvelope.push_back({newLine, cross(newLine, upperEnvelope.back().first)}); } } Line query(long long x) { /*cout << "now query " << x << endl; for (auto [line, point] : upperEnvelope) { cout << line.idx << " " << point << endl; }*/ int l = 0; int r = upperEnvelope.size() - 1; while (l <= r) { int mid = (l + r) / 2; if (upperEnvelope[mid].second <= 1.0 * x) { l = mid + 1; } else { r = mid - 1; } } return upperEnvelope[r].first; } }; ConvexHullTrickMAX cht[maxk]; void fastIO() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); } int main() { fastIO(); cin >> n >> k; for (int i = 1; i <= n; ++i) { cin >> a[i]; pref[i] = pref[i - 1] + a[i]; } for (int i = 1; i <= n; ++i) { for (int j = 0; j <= min(i - 1, k); ++j) { if (j != 0) { Line curr = cht[j - 1].query(pref[i]); dp[j] = curr.calc(pref[i]); prvState[i][j] = curr.idx; } else { dp[j] = 0; } //cout << i << " " << j << " :: " << dp[i][j] << endl; } for (int j = 0; j <= min(i - 1, k); ++j) { //cout << "add " << j << " " << pref[i] << " :: " << dp[i][j] - pref[i] * pref[i] << endl;; cht[j].addLine({pref[i], dp[j] - pref[i] * pref[i], i}); } //cout << "end of " << i << endl; //cout << "------------------------------" << endl; } long long ans = dp[k]; int pos = n; stack<int> splits; while (k > 0) { splits.push(prvState[pos][k]); pos = splits.top(); --k; } cout << ans << endl; while (!splits.empty()) { cout << splits.top() << " "; splits.pop(); } cout << endl; return 0; } /* 6 1 0 0 0 0 1 1 7 3 4 1 3 4 0 2 3 2 1 4 3 1 16 3 2 19 4 1 35 4 2 48 4 3 51 5 1 35 5 2 48 5 3 51 6 1 48 6 2 64 6 3 72 7 1 72 7 2 95 7 3 108 */
#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...