Submission #697913

#TimeUsernameProblemLanguageResultExecution timeMemory
697913bebraSplit the sequence (APIO14_sequence)C++17
100 / 100
1814 ms87428 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define dbg(x) cerr << #x << ": " << x << endl; struct Line { ll k; ll b; Line(ll _k = 0, ll _b = 0) : k(_k), b(_b) {} ll get(ll x) const { return k * x + b; } friend double intersect(const Line& lhs, const Line& rhs) { return (double)(lhs.b - rhs.b) / (rhs.k - lhs.k); } }; struct CHT : vector<Line> { int n; vector<int> indices; CHT() { n = 0; } void add_line(ll k, ll b, int idx) { Line new_line(k, b); while (n > 0 && back().k == k) { if (back().b > new_line.b) { new_line.b = back().b; idx = indices.back(); } --n; pop_back(); indices.pop_back(); } while (n >= 2 && intersect(at(n - 1), at(n - 2)) > intersect(at(n - 2), new_line)) { --n; pop_back(); indices.pop_back(); } ++n; push_back(new_line); indices.push_back(idx); } pair<ll, int> get_max(ll x) { int l = -1; int r = n - 1; while (l != r - 1) { int m = (l + r) / 2; if (intersect(at(m), at(m + 1)) < (double)x) { l = m; } else { r = m; } } return {at(r).get(x), indices[r]}; } }; const int MAX_N = 1e5 + 5; const int MAX_K = 200 + 5; int p[MAX_N][MAX_K]; ll a[MAX_N]; ll pref[MAX_N]; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k; ll total_sum = 0; for (int i = 1; i <= n; ++i) { cin >> a[i]; pref[i] = pref[i - 1] + a[i]; total_sum += a[i]; } CHT lines; vector<ll> dp(n); for (int i = 1; i < n; ++i) { dp[i] = pref[i] * (total_sum - pref[i]); } for (int j = 2; j <= k; ++j) { vector<ll> new_dp(n); for (int i = 1; i < n; ++i) { if (i >= j) { tie(new_dp[i], p[i][j]) = lines.get_max(pref[i]); new_dp[i] += pref[i] * (total_sum - pref[i]); } lines.add_line(pref[i], dp[i] - pref[i] * total_sum, i); } CHT new_lines; swap(lines, new_lines); swap(dp, new_dp); } ll ans = 0; int opt = -1; for (int i = 1; i < n; ++i) { if (dp[i] >= ans) { ans = dp[i]; opt = i; } } vector<int> splits; int curr_i = opt; int curr_k = k; while (curr_k > 0) { splits.push_back(curr_i); curr_i = p[curr_i][curr_k]; --curr_k; } reverse(splits.begin(), splits.end()); cout << ans << '\n'; for (auto x : splits) { cout << x << ' '; } cout << '\n'; return 0; } /* 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...