Submission #957255

#TimeUsernameProblemLanguageResultExecution timeMemory
957255alextodoranChorus (JOI23_chorus)C++17
100 / 100
2521 ms45816 KiB
/** _ _ __ _ _ _ _ _ _ |a ||t ||o d | |o | | __ _| | _ | __| _ | | __ |/_ | __ /__\ / _\| **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; const int N_MAX = 1000000; const ll INF = LLONG_MAX; int N, K; int A[N_MAX + 2]; ll suff[N_MAX + 2]; ll dp[N_MAX + 2]; int cnt[N_MAX + 2]; struct Line { ll a, b; ll f (int x) { return a * x + b; } }; Line lines[N_MAX + 2]; deque <int> rel; bool check (const Line &l1, const Line &l2, const Line &l3) { return (l2.b - l1.b) * (l2.a - l3.a) < (l3.b - l2.b) * (l1.a - l2.a); } void add_line (int j) { while ((int) rel.size() >= 2 && check(lines[rel.end()[-2]], lines[rel.back()], lines[j]) == false) { rel.pop_back(); } rel.push_back(j); } pair <ll, int> query (int i) { if (rel.empty() == true) { return make_pair(INF, 0); } while ((int) rel.size() >= 2 && make_pair(lines[rel[0]].f(i), cnt[rel[0]]) >= make_pair(lines[rel[1]].f(i), cnt[rel[1]])) { rel.pop_front(); } return make_pair(lines[rel.front()].f(i) - suff[i + 1], cnt[rel.front()]); } ll solve (ll pen) { rel.clear(); deque <int> dq; int curr = 0; for (int i = 1; i <= N; i++) { for (int j = curr; j < min(A[i] - i, i); j++) { // dp[j] + sum(A[i1] + i1 - j | i <= i1 <= i2) // dp[j] + suff[i] - suff[i2 + 1] - j * i2 + j * (i - 1) lines[j].a = -j; lines[j].b = dp[j] + suff[i] + (ll) j * (i - 1); add_line(j); } curr = min(A[i] - i, i); while (dq.empty() == false && dp[i - 1] < dp[dq.back()]) { dq.pop_back(); } dq.push_back(i - 1); while (dq.empty() == false && dq.front() < curr) { dq.pop_front(); } tie(dp[i], cnt[i]) = query(i); if (dq.empty() == false) { int j = dq.front(); if (make_pair(dp[j], cnt[j]) < make_pair(dp[i], cnt[i])) { dp[i] = dp[j]; cnt[i] = cnt[j]; } } dp[i] += pen; cnt[i]++; } return dp[N] - pen * K; } int main () { ios_base::sync_with_stdio(false); cin.tie(0); cin >> N >> K; string S; cin >> S; for (int i = 0, j = 0; i < N * 2; i++) { if (S[i] == 'A') { A[++j] = i + 1; } } for (int i = N; i >= 1; i--) { suff[i] = suff[i + 1] + A[i] - i; } ll l = 0, r = LLONG_MAX / 2; while (l < r) { ld mid = (l + r) / 2; solve(mid); if (cnt[N] <= K) { r = mid; } else { l = mid + 1; } } cout << solve(l) << "\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...