Submission #102911

#TimeUsernameProblemLanguageResultExecution timeMemory
102911beobeoSplit the sequence (APIO14_sequence)C++14
0 / 100
42 ms5100 KiB
/* Problem URL: https://oj.uz/problem/view/APIO14_sequence Tags: dp, convex hull optimization */ #include <iostream> #include <vector> #include <deque> #include <stack> #include <algorithm> using namespace std; const int N = 100005; long long a[N]; struct Line { long long a, b; int idx; long long GetCost(long long x) { return a * (x - a) + b; } double Intersect(const Line& l) { return (double)(b - l.b) / (l.a - a); } long long To(Line& rhs) { long long lo = max(a, rhs.a); long long hi = 1LL << 60; while (lo < hi) { long long mid = (lo + hi) / 2; long long v1 = GetCost(mid); long long v2 = rhs.GetCost(mid); if (v1 <= v2) { hi = mid; } else { lo = mid + 1; } } return hi; } }; bool Check(Line& l1, Line& l2, Line& l3) { return 1.0 * (l3.b - l2.b) * (l1.a - l2.a) > 1.0 * (l2.b - l1.b) * (l2.a - l3.a); } int main() { int n, k; cin >> n >> k; for (int i = 0; i < n; i++) { cin >> a[i]; } vector<long long> sums(n + 1); for (int i = 0; i < n; i++) { sums[i + 1] = sums[i] + a[i]; } vector<long long> dp1(n + 1); vector<long long> dp2(n + 1); vector<vector<int>> splits(k, vector<int>(n + 1)); for (int i = 0; i < k; i++) { deque<Line> lines; for (int j = i + 1; j <= n; j++) { while (lines.size() > 1 && lines[0].GetCost(sums[j]) <= lines[1].GetCost(sums[j])) { lines.pop_front(); } if (!lines.empty()) { dp2[j] = lines[0].GetCost(sums[j]); splits[i][j] = lines[0].idx; } Line l({sums[j], dp1[j], j}); while (lines.size() > 1 && lines[lines.size() - 2].Intersect(lines.back()) <= lines.back().Intersect(l)) { lines.pop_back(); } // while (lines.size() > 1 && Check(lines[lines.size() - 2], lines[lines.size() - 1], l)) { // lines.pop_back(); // } // while (lines.size() > 1) { // long long t1 = lines[lines.size() - 2].To(lines[lines.size() - 1]); // long long t2 = lines[lines.size() - 1].To(l); // if (t1 >= t2) break; // else lines.pop_back(); // } lines.push_back(l); } // for (int j = 0; j <= n; j++) { // cout << dp2[j] << ' '; // } // cout << endl; dp1 = dp2; } cout << dp2[n] << endl; stack<int> st; for (int i = k - 1, j = n; i >= 0; i--) { j = splits[i][j]; st.push(j); } while (!st.empty()) { cout << st.top() << ' '; st.pop(); } }
#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...