Submission #882831

#TimeUsernameProblemLanguageResultExecution timeMemory
882831MilosMilutinovicChorus (JOI23_chorus)C++14
100 / 100
5729 ms71900 KiB
#include <bits/stdc++.h> using namespace std; struct line { long long k, n; int f; void init() { k = 0; n = (long long) 1e18; f = 0; } long long val(long long x) { return k * x + n; } }; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, k; cin >> n >> k; string s; cin >> s; vector<int> a, b; for (int i = 0; i < 2 * n; i++) { if (s[i] == 'A') { a.push_back(i); } else { b.push_back(i); } } vector<int> ia(2 * n); for (int i = 0; i < n; i++) { ia[a[i]] = i + 1; } vector<long long> pref(2 * n); for (int i = 0; i < 2 * n; i++) { if (i > 0) { pref[i] = pref[i - 1]; } pref[i] += (s[i] == 'A' ? 1 : 0); } vector<int> ib(2 * n); for (int i = 0; i < n; i++) { ib[b[i]] = pref[b[i]]; } for (int i = 0; i < n; i++) { if (i > 0) { pref[i] = pref[i - 1]; } else { pref[i] = 0; } pref[i] += ib[b[i]]; } deque<line> hull; auto Update = [&](line c) { while ((int) hull.size() >= 2) { line a = hull.rbegin()[1]; line b = hull.back(); long long x_ab = (b.n - a.n) * 1LL * (a.k - c.k); long long x_ac = (c.n - a.n) * 1LL * (a.k - b.k); if (x_ab > x_ac || (x_ab == x_ac && b.f >= c.f)) { hull.pop_back(); } else { break; } } hull.push_back(c); }; auto Query = [&](int x) { while ((int) hull.size() >= 2 && (hull.front().val(x) > hull[1].val(x) || (hull.front().val(x) == hull[1].val(x) && hull.front().f >= hull[1].f))) { hull.pop_front(); } return make_pair(hull.front().val(x), hull.front().f); }; auto Solve = [&](long long mid) { const long long inf = (long long) 1e18; vector<pair<long long, int>> dp(n + 1, {inf, 0}); dp[0] = {0, 0}; int ptr = -1; multiset<pair<long long, int>> st; hull.clear(); for (int i = 0; i < n; i++) { st.insert(dp[i]); while (ptr + 1 <= i && ia[a[i]] >= ib[b[ptr + 1]]) { ptr += 1; line cur; cur.k = -ptr; cur.n = dp[ptr].first + (ptr == 0 ? 0 : pref[ptr - 1]) + mid; cur.f = dp[ptr].second; Update(cur); st.erase(st.find(dp[ptr])); } if (!st.empty()) { pair<long long, int> val = *st.begin(); dp[i + 1] = min(dp[i + 1], {val.first + mid, val.second + 1}); } if (ptr != -1) { pair<long long, int> val = Query(ia[a[i]]); dp[i + 1] = min(dp[i + 1], {val.first + ia[a[i]] * 1LL * (ptr + 1) - pref[ptr], val.second + 1}); } } return dp[n]; }; long long low = 0, high = 1e12, p = 0; while (low <= high) { long long mid = low + high >> 1; pair<long long, int> res = Solve(mid); if (res.second <= k) { p = mid; high = mid - 1; } else { low = mid + 1; } } pair<long long, int> res = Solve(p); cout << res.first - p * k << '\n'; return 0; }

Compilation message (stderr)

chorus.cpp: In function 'int main()':
chorus.cpp:109:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  109 |     long long mid = low + high >> 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...