Submission #231443

#TimeUsernameProblemLanguageResultExecution timeMemory
231443peijarSplit the sequence (APIO14_sequence)C++17
71 / 100
322 ms131072 KiB
#include <bits/stdc++.h> using namespace std; #define SZ(v) ((int)(v).size()) using ll = long long; // convex hull, maximum struct LineContainer { struct Line { ll a, b, id; }; deque<Line> lines; inline ll intersect(Line l1, Line l2) // l1.a < l2.a { return (l1.b - l2.b)/(l2.a - l1.a); } bool bad_line(Line l1, Line l2, Line l3) { return (l1.b - l3.b) * (l2.a - l1.a) <= (l1.b - l2.b) * (l3.a - l1.a); } // Increasing a ! void add_line(ll a, ll b, int id) { Line l = {a, b, id}; if (SZ(lines) and lines.back().a == l.a) if (lines.back().b >= l.b) return ; while (SZ(lines) >= 2 and bad_line(lines[SZ(lines) - 2], lines.back(), l)) lines.pop_back(); lines.push_back(l); } inline ll get_val(Line l, ll x) { return x * l.a + l.b; } // Increasing x ! pair<ll, int> query(ll x) { while (SZ(lines) >= 2 and get_val(lines[0], x) <= get_val(lines[1], x)) lines.pop_front(); return make_pair(get_val(lines[0], x), lines[0].id); } }; const int MAXN = 1e5+1; const int MAXK = 201; ll dp[MAXK][MAXN]; ll arr[MAXN]; ll transition[MAXK][MAXN]; int nb_elem; int main(void) { int nb_split; cin >> nb_elem >> nb_split; for (int i(0); i < nb_elem; ++i) cin >> arr[i]; vector<ll> suffix_sum(nb_elem+1); suffix_sum[nb_elem] = 0; for (int i(nb_elem-1); i >= 0; --i) suffix_sum[i] = suffix_sum[i+1] + arr[i]; for (int splits(1); splits <= nb_split; ++splits) dp[splits][nb_elem-1] = -1; for (int splits(1); splits <= nb_split; ++splits) { LineContainer cht; for (int id(nb_elem -2); id >= 0; --id) { if (dp[splits-1][id+1] >= 0) cht.add_line(suffix_sum[id+1], dp[splits-1][id+1] - suffix_sum[id+1] * suffix_sum[id+1], id); if (SZ(cht.lines)) { auto [val, nxt] = cht.query(suffix_sum[id]); dp[splits][id] = val; transition[splits][id] = nxt; } else dp[splits][id] = -1; } } cout << dp[nb_split][0] << endl; int cur(0); for (int i(0); i < nb_split; ++i) { assert(dp[nb_split-i][cur] >= 0); cur = transition[nb_split-i][cur] + 1; cout << cur << ' '; } cout << endl; }
#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...