Submission #788563

#TimeUsernameProblemLanguageResultExecution timeMemory
788563someoneChorus (JOI23_chorus)C++14
61 / 100
12 ms1620 KiB
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 5e3 + 42, INF = 1e12 + 42; vector<int> pre, upd[N]; deque<int> imin, a, b, c; int n, k, cumul[N], fi[N], dp[N], nbT[N]; int evalCHT(int x) { while((int)a.size() >= 2 && (a[0] * x + b[0] > a[1] * x + b[1] || (a[0] * x + b[0] == a[1] * x + b[1] && c[0] >= c[1]))) { a.pop_front(); b.pop_front(); c.pop_front(); } return a[0] * x + b[0]; } void pushCHT(int A, int B, int C) { int sz = (int)a.size(); while(sz >= 2 && (B - b[sz-1]) * (a[sz-2] - a[sz-1]) <= (b[sz-1] - b[sz-2]) * (a[sz-1] - A)) { sz--; a.pop_back(); b.pop_back(); c.pop_back(); } a.push_back(A); b.push_back(B); c.push_back(C); } void add(int i) { if(fi[i] == i) { pushCHT(-i, dp[i] + i * fi[i] - cumul[fi[i]], nbT[i]); return; } upd[fi[i]].push_back(i); while(!imin.empty() && (dp[imin.back()] > dp[i] || (dp[imin.back()] == dp[i] && nbT[imin.back()] > nbT[i]))) imin.pop_back(); imin.push_back(i); } pair<int, int> solve(int lambda) { a.clear(); b.clear(); c.clear(); imin.clear(); for(int i = 0; i < N; i++) upd[i].clear(); add(0); for(int i = 1; i <= n; i++) { for(int j : upd[i]) { pushCHT(-j, dp[j] + j * fi[j] - cumul[fi[j]], nbT[j]); if(!imin.empty() && imin[0] == j) imin.pop_front(); } dp[i] = evalCHT(i) + cumul[i]; nbT[i] = c[0]; if(!imin.empty()) if(dp[imin[0]] < dp[i] || (dp[imin[0]] == dp[i] && nbT[imin[0]] < dp[i])) nbT[i] = nbT[imin[0]]; nbT[i]++; dp[i] += lambda; add(i); } return {dp[n], nbT[n]}; } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int x = 0; cin >> n >> k; for(int i = 0; i < N; i++) fi[i] = N-1; pre.clear(); int nbA = 0; for(int i = 0; i < 2*n; i++) { char ch; cin >> ch; if(ch == 'A') { nbA++; if(fi[x] == N-1) fi[x] = (int)pre.size(); pre.push_back(x); } else { x++; } } for(int i = n-1; i > -1; i--) if(fi[i] == N-1) fi[i] = fi[i+1]; for(int i = 0; i <= n; i++) fi[i] = max(fi[i], i); for(int i = 1; i <= n; i++) cumul[i] = cumul[i-1] + pre[i-1]; int deb = 0, fin = INF; while(fin - deb > 1) { int mid = ((deb + fin) >> 1); auto pii = solve(mid-1); if(pii.second <= k) fin = mid; else deb = mid; } cout << solve(deb).first - k * deb << '\n'; }
#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...