Submission #259212

#TimeUsernameProblemLanguageResultExecution timeMemory
259212EntityITSplit the sequence (APIO14_sequence)C++14
100 / 100
995 ms87472 KiB
#include <bits/stdc++.h> using namespace std; #define ALL(x) (x).begin(), (x).end() #define SZ(x) static_cast<int>((x).size()) template<class T, size_t D> struct vec : vector<vec<T, D - 1>> { template<class... Args> vec(size_t n = 0, Args... args) : vector<vec<T, D - 1>>(n, vec<T, D - 1>(args...)) {} }; template<class T> struct vec<T, 1> : vector<T> { template<class... Args> vec(Args... args) : vector<T>(args...) {} }; template<class T> inline bool Minimize(T& a, const T& b) { return a > b ? a = b, true : false; } template<class T> inline bool Maximize(T& a, const T& b) { return a < b ? a = b, true : false; } inline int Next(int i, int n) { return i == n - 1 ? 0 : i + 1; } inline int Prev(int i, int n) { return !i ? n - 1 : i - 1; } mt19937 rng(static_cast<uint32_t>(chrono::steady_clock::now().time_since_epoch().count())); struct Line { int a; int64_t b; int label; Line(int t_a = 0, int64_t t_b = 0, int t_label = 0) : a(t_a), b(t_b), label(t_label) {} int64_t y(int x) { return static_cast<int64_t>(a) * x + b; } }; struct ConvexHullTrick { vector<Line> lines; int index_line; ConvexHullTrick() : lines(), index_line(-1) {} bool Bad(Line line_1, Line line_2, Line line_3) { return static_cast<double>(line_1.b - line_3.b) / (line_3.a - line_1.a) <= static_cast<double>(line_1.b - line_2.b) / (line_2.a - line_1.a); } void AddLine(Line line) { if (SZ(lines) && line.a == lines.back().a) { if (line.b <= lines.back().b) { return; } lines.pop_back(); Minimize(index_line, SZ(lines) - 1); } while (SZ(lines) > 1 && Bad(lines.rbegin()[1], lines.back(), line)) { lines.pop_back(); Minimize(index_line, SZ(lines) - 1); } lines.emplace_back(line); } int Get(int x) { for (; index_line + 1 < SZ(lines) && (!~index_line || lines[index_line].y(x) < lines[index_line + 1].y(x)); ++index_line); return index_line; } }; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, n_cuts; cin >> n >> n_cuts; vec<int, 1> prefix_sums(n + 1); for (int i = 0; i < n; ++i) { int a; cin >> a; prefix_sums[i + 1] = prefix_sums[i] + a; } vec<int64_t, 1> f(n + 1), next_f(n + 1); vec<int, 2> trace(n_cuts + 1, n + 1); for (int i = 1; i <= n_cuts; ++i) { ConvexHullTrick cht; for (int j = i + 1; j <= n; ++j) { cht.AddLine(Line(prefix_sums[j - 1], f[j - 1] - static_cast<int64_t>(prefix_sums[j - 1]) * prefix_sums[j - 1], j - 1)); int index_line = cht.Get(prefix_sums[j]); assert(~index_line); next_f[j] = cht.lines[index_line].y(prefix_sums[j]); trace[i][j] = cht.lines[index_line].label; } f.swap(next_f); } cout << f[n] << '\n'; vec<int, 1> positions; for (int i = n_cuts, j = n; i; --i) { positions.emplace_back((j = trace[i][j])); } reverse(ALL(positions)); for (auto& position : positions) { cout << position << ' '; } cout << '\n'; return 0; }
#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...