Submission #934508

#TimeUsernameProblemLanguageResultExecution timeMemory
934508boris_mihovChorus (JOI23_chorus)C++17
100 / 100
1661 ms44052 KiB
#include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <vector> #include <queue> typedef long long llong; const int MAXN = 1000000 + 10; const llong INF = 1e18; int n, k; struct ConvexHullTrick { struct Line { llong a, b; int cntPenalties; llong to; std::pair <llong,int> at(llong x) { return {x * a + b, cntPenalties}; } }; std::deque <Line> cht; llong intersect(Line x, Line y) { assert(x.a > y.a); assert(x.b < y.b); return (y.b - x.b) / (x.a - y.a) - (((y.b - x.b) % (y.a - x.a) == 0) && x.cntPenalties < y.cntPenalties); } void push(Line l) { while (cht.size() && cht.back().at(cht.back().to) > l.at(cht.back().to)) { cht.pop_back(); } if (cht.empty()) cht.push_back(l); else if (cht.back().at(0) > l.at(0)) cht.push_back({l.a, l.b, l.cntPenalties, intersect(l, cht.back())}); } std::pair <llong,int> query(llong x) { assert(cht.size()); while (cht.size() > 1 && x <= cht[1].to) { cht.pop_front(); } return cht[0].at(x); } }; int h[MAXN]; int next[MAXN]; llong prefix[MAXN]; std::pair <llong,int> dp[MAXN]; char s[2 * MAXN]; std::pair <llong,int> calc(llong penalty) { dp[n + 1] = {0, 0}; ConvexHullTrick cht; cht.push({-(n + 1), dp[n + 1].first + prefix[n], dp[n + 1].second, n}); int ptr = n + 1; for (int pos = n ; pos >= 1 ; --pos) { dp[pos] = {INF, 0}; if (pos < next[pos]) { dp[pos] = dp[next[pos]]; dp[pos].first += penalty; dp[pos].second++; } while (ptr - 1 > std::max(pos, next[pos])) { ptr--; cht.push({-ptr, prefix[ptr - 1] + dp[ptr].first, dp[ptr].second, n}); } llong addedValue = 1LL * (next[pos] - pos + 1) * (pos - 1) + 1LL * pos * (pos - 1) - prefix[next[pos]] + penalty; std::pair <llong,int> res = cht.query(pos - 1); res.first += addedValue; res.second += 1; dp[pos] = std::min(dp[pos], res); } return dp[1]; } void solve() { int cntA = 0; int cntB = 0; for (int i = 1 ; i <= 2 * n ; ++i) { if (s[i] == 'B') { cntB++; } else { cntA++; h[cntA] = cntB; } } for (int i = 1 ; i <= n ; ++i) { prefix[i] = prefix[i - 1] + h[i]; } next[n + 1] = n + 1; h[n + 1] = n + 1; for (int i = n ; i >= 1 ; --i) { next[i] = next[i + 1]; while (next[i] >= i && h[next[i]] >= i) { next[i]--; } } llong l = -1, r = 1LL * n * n, mid; while (l < r - 1) { mid = (l + r) / 2; if (calc(mid).second > k) l = mid; else r = mid; } auto [fL, groupsL] = calc(l); auto [fR, groupsR] = calc(r); fL -= groupsL * l; fR -= groupsR * r; if (groupsR == k) { std::cout << fR << '\n'; return; } std::cout << fL + (fR - fL) * (groupsL - k) / (groupsL - groupsR) << '\n'; } void input() { std::cin >> n >> k; std::cin >> s + 1; } void fastIOI() { std::ios_base :: sync_with_stdio(0); std::cout.tie(nullptr); std::cin.tie(nullptr); } int main() { fastIOI(); input(); solve(); return 0; }

Compilation message (stderr)

chorus.cpp: In function 'void input()':
chorus.cpp:155:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  155 |     std::cin >> s + 1;
      |                 ~~^~~
#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...