Submission #255443

#TimeUsernameProblemLanguageResultExecution timeMemory
255443rama_pangSplit the sequence (APIO14_sequence)C++14
100 / 100
148 ms6772 KiB
#include <bits/stdc++.h> using namespace std; using lint = long long; const int MAXN = 1e5 + 5; struct Line { int id, cnt; lint a, b; Line() {} Line(int id, int cnt, lint a, lint b) : id(id), cnt(cnt), a(a), b(b) {} pair<lint, int> get(lint x) { return {a * x + b, cnt}; } }; class ConvexHull { public: ConvexHull() {} int sz, ptr = 0; vector<Line> line; void Clear() { ptr = 0, line.clear(); } bool Majorize(Line a, Line b, Line c) { return make_tuple((1.00 * (c.b - a.b) / (a.a - c.a)), -c.cnt, c.id) < make_tuple((1.00 * (b.b - a.b) / (a.a - b.a)), -b.cnt, b.id); } void Insert(Line n) { sz = line.size(); if (!line.empty() && line.back().a == n.a) { if (n.b < line.back().b) { n = line.back(); } line.pop_back(); } while (ptr + 1 < sz && Majorize(line[sz - 2], line[sz - 1], n)) { line.pop_back(); sz--; } line.emplace_back(n); } tuple<lint, int, int> Query(lint x) { while (ptr + 1 < (int) line.size() && line[ptr].get(x) <= line[ptr + 1].get(x)) { ptr++; } return make_tuple(line[ptr].get(x).first, line[ptr].cnt, line[ptr].id); } }; int N, K; lint A[MAXN]; ConvexHull cht; int prv[MAXN]; pair<lint, int> dp[MAXN]; void Trial(lint lambda, int sign) { cht.Clear(); for (int i = 1; i <= N; i++) { cht.Insert(Line(i - 1, dp[i - 1].second, A[i - 1], dp[i - 1].first - A[i - 1] * A[i - 1])); lint x; int y, z; tie(x, y, z) = cht.Query(A[i]); dp[i] = make_pair(x - lambda, y + sign); prv[i] = z; } } vector<int> Trace(lint lambda, int sign) { Trial(lambda, sign); vector<int> res; for (int cur = N; cur > 0; cur = prv[cur]) { res.emplace_back(cur); } res.emplace_back(0); reverse(begin(res), end(res)); return res; } void Answer(vector<int> res) { lint ans = 0; for (int i = 1; i < (int) res.size(); i++) { ans += (A[res[i]] - A[res[i - 1]]) * A[res[i - 1]]; } cout << ans << "\n"; for (int i = 1; i + 1 < (int) res.size(); i++) { if (i > 1) { cout << " "; } cout << res[i]; } cout << "\n"; exit(0); } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin >> N >> K; K++; for (int i = 1; i <= N; i++) { cin >> A[i]; A[i] += A[i - 1]; } lint lo = 0, hi = 1e17; while (lo < hi) { lint md = (lo + hi) / 2; Trial(md, -1); if (-dp[N].second <= K) { hi = md; } else { lo = md + 1; } } auto minim = Trace(lo, -1); auto maxim = Trace(lo, +1); if (minim.size() == K + 1) Answer(minim); if (maxim.size() == K + 1) Answer(maxim); for (int i = 1, j = 0; i < (int) maxim.size(); i++) { while (minim[j] <= maxim[i - 1]) { j++; } if (minim[j] >= maxim[i] && i + (int) minim.size() - j == K + 1) { vector<int> res; for (int k = 0; k < i; k++) { res.emplace_back(maxim[k]); } for (int k = j; k < (int) minim.size(); k++) { res.emplace_back(minim[k]); } Answer(res); } } return 0; }

Compilation message (stderr)

sequence.cpp: In function 'int main()':
sequence.cpp:121:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (minim.size() == K + 1) Answer(minim);
       ~~~~~~~~~~~~~^~~~~~~~
sequence.cpp:122:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (maxim.size() == K + 1) Answer(maxim);
       ~~~~~~~~~~~~~^~~~~~~~
#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...