Submission #1011820

#TimeUsernameProblemLanguageResultExecution timeMemory
1011820baodeptraiSplit the sequence (APIO14_sequence)C++14
71 / 100
60 ms131072 KiB
#include <bits/stdc++.h> using namespace std; #define endl "\n" #define ll long long template <bool kGetMin = false> struct LineDeque { using T = long long; struct Line { mutable T a, b, p; bool operator<(const Line &other) const { return a < other.a; } bool operator<(T x) const { return p < x; } T eval(T x) const { return a * x + b; } }; using Set = std::deque<pair<Line, int>>; using Iterator = typename Set::iterator; Set s; static const T inf = std::numeric_limits<T>::max(); // doubles: inf = 1/.0, div(a, b) = a / b T div(T a, T b) { // floored division return a / b - ((a ^ b) < 0 && a % b); } bool intersect(Line &x, Line &y) { if (x.a == y.a) { x.p = x.b > y.b ? inf : -inf; } else { x.p = div(y.b - x.b, x.a - y.a); } return x.p >= y.p; } void _add_line1(T a, T b, int id) { // increasing slope Line to_add = {a, b, inf}; if (s.size()) { intersect(s.back().first, to_add); } while (s.size() >= 2 && intersect(s.at(s.size() - 2).first, s.at(s.size() - 1).first)) { s.pop_back(); intersect(s.back().first, to_add); } s.push_back({to_add, id}); } void _add_line2(T a, T b, int id) { // decreasing slope Line to_add = {a, b, 0}; while (s.size() && intersect(to_add, s.front())) { s.pop_front(); } s.push_front({to_add, id}); } void add_line_increasing_slope(T a, T b, int id) { if constexpr (kGetMin) { _add_line2(-a, -b, id); } else { _add_line1(a, b, id); } } void add_line_decreasing_slope(T a, T b, int id) { if constexpr (kGetMin) { _add_line1(-a, -b, id); } else { _add_line2(a, b, id); } } T query(T x) { // arbitrary assert(!s.empty()); auto l = *std::lower_bound(s.begin(), s.end()); // To get min if constexpr (kGetMin) { return -l.eval(x); } else { return l.eval(x); } } pair<T, int> query_increasing(T x) { while (s.size() >= 2 && s[0].first.eval(x) <= s[1].first.eval(x)) { s.pop_front(); } if constexpr (kGetMin) { return {-s[0].first.eval(x), s[0].second}; } else { return {s[0].first.eval(x), s[0].second}; } } pair<T, int> query_decreasing(T x) { while (s.size() >= 2 && s.at(s.size() - 1).first.eval(x) <= s.at(s.size() - 2).first.eval(x)) { s.pop_back(); } if constexpr (kGetMin) { return {-s[0].first.eval(x), s[0].second}; } else { return {s[0].first.eval(x), s[0].second}; } } }; int n, k, a[100005]; ll s[100005]; pair<ll, int> dp[100005][250]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> k; vector<int> res; for (int i = 1; i <= n; i++) { cin >> a[i]; s[i] = s[i - 1] + a[i]; } LineDeque<false> d[205]; // res.push_back(1); for (int i = 1; i <= k; i++) { // d[i - 1].add_line_increasing_slope(s[0], dp[0][i - 1].first - s[0] * s[0], 0); for (int j = 1; j <= n; j++) { auto val = d[i - 1].query_increasing(s[j]); dp[j][i] = val; d[i - 1].add_line_increasing_slope(s[j], dp[j][i - 1].first - s[j] * s[j], j); } } int x = n; int the = k; // while (the != 0) // { // int y = dp[x][the].second; // res.push_back(y); // res.push_back(x); // // cout << x << " " << y << endl; // x = y - 1; // the--; // } for (int i = k; i >= 1; i--) { res.push_back(dp[x][i].second); x = dp[x][i].second; } reverse(res.begin(), res.end()); cout << dp[n][k].first << endl; for (int i : res) { cout << i << " "; } }

Compilation message (stderr)

sequence.cpp: In member function 'void LineDeque<kGetMin>::add_line_increasing_slope(LineDeque<kGetMin>::T, LineDeque<kGetMin>::T, int)':
sequence.cpp:70:12: warning: 'if constexpr' only available with '-std=c++17' or '-std=gnu++17'
   70 |         if constexpr (kGetMin)
      |            ^~~~~~~~~
sequence.cpp: In member function 'void LineDeque<kGetMin>::add_line_decreasing_slope(LineDeque<kGetMin>::T, LineDeque<kGetMin>::T, int)':
sequence.cpp:82:12: warning: 'if constexpr' only available with '-std=c++17' or '-std=gnu++17'
   82 |         if constexpr (kGetMin)
      |            ^~~~~~~~~
sequence.cpp: In member function 'LineDeque<kGetMin>::T LineDeque<kGetMin>::query(LineDeque<kGetMin>::T)':
sequence.cpp:97:12: warning: 'if constexpr' only available with '-std=c++17' or '-std=gnu++17'
   97 |         if constexpr (kGetMin)
      |            ^~~~~~~~~
sequence.cpp: In member function 'std::pair<long long int, int> LineDeque<kGetMin>::query_increasing(LineDeque<kGetMin>::T)':
sequence.cpp:113:12: warning: 'if constexpr' only available with '-std=c++17' or '-std=gnu++17'
  113 |         if constexpr (kGetMin)
      |            ^~~~~~~~~
sequence.cpp: In member function 'std::pair<long long int, int> LineDeque<kGetMin>::query_decreasing(LineDeque<kGetMin>::T)':
sequence.cpp:129:12: warning: 'if constexpr' only available with '-std=c++17' or '-std=gnu++17'
  129 |         if constexpr (kGetMin)
      |            ^~~~~~~~~
sequence.cpp: In function 'int main()':
sequence.cpp:166:9: warning: unused variable 'the' [-Wunused-variable]
  166 |     int the = k;
      |         ^~~
#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...