제출 #1130463

#제출 시각아이디문제언어결과실행 시간메모리
1130463Math4Life2020Chorus (JOI23_chorus)C++20
61 / 100
7091 ms7624 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<ll,ll>; const ll Nm = 1e6+5; const ll INF = 1e9; ll c[Nm]; ll psc[Nm+1]; ll io[Nm]; //first i with c[i0]-l>=0 ll N; pii fz(pii p1, pii p2) { if (p1.first<p2.first) { return p1; } if (p1.first>p2.first) { return p2; } if (p1.second<p2.second) { return p1; } else { return p2; } } vector<array<ll,3>> chull; pii qryH(ll x) { pii pf = {INF,INF}; for (auto A0: chull) { pf = fz(pf,{A0[0]+A0[1]*x,A0[2]}); } return pf; } pii qry(ll Ctest) { chull.clear(); pii dp[N+1]; //{cost,# used} for (ll i=1;i<=N;i++) { dp[i]={INF,INF}; } dp[0]={0,0}; deque<pii> d0; vector<array<ll,3>> lns[N+1]; for (ll l=0;l<=N;l++) { //process // cout << "\nprocess l="<<l<<"\n"; // cout << "i0="<<io[l]<<"\n"; for (auto A0: lns[l]) { chull.push_back(A0); } dp[l]=fz(dp[l],qryH(l-1)); //cout << "dp[l]="<<dp[l].first<<","<<dp[l].second<<"\n"; if (dp[l].first==INF) { continue; } if (io[l]==N) { dp[N]=fz(dp[N],{dp[l].first+Ctest,dp[l].second+1}); } else { array<ll,3> A0 = {Ctest+dp[l].first+psc[l]-psc[io[l]]+l*(io[l]-1),-l,dp[l].second+1}; //cout << "A0: "<<A0[0]<<","<<A0[1]<<","<<A0[2]<<"\n"; //lns[io[l]].push_back({Ctest+dp[l].first+psc[l]-psc[io[l]]+l*(io[l]-1),-l,dp[l].second+1}); if (io[l]==l) { chull.push_back(A0); } else { lns[io[l]].push_back(A0); } } } return {dp[N].first-dp[N].second*Ctest,dp[N].second}; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); ll K; cin >> N >> K; string s; cin >> s; ll i0 = 0; ll c0 = 0; psc[0]=0; for (ll i=0;i<(2*N);i++) { if (s[i]=='A') { c[i0]=c0; psc[i0+1]=psc[i0]+c[i0]; //cout << "i0="<<i0<<", c[i0]="<<c[i0]<<"\n"; i0++; } else { assert(s[i]=='B'); c0++; } } ll iov = N; io[N]=N; for (ll l=(N-1);l>=0;l--) { while (iov>0 && (c[iov-1]>=l)) { iov--; } io[l]=max(l,iov); } // for (ll q=0;q<=25;q++) { // cout << "q="<<q<<"\n"; // pii p0 = qry(q); // cout << "query value="<<p0.first<<","<<p0.second<<"\n"; // } //exit(0); ll Cmin = 0; ll Cmax = INF/2; //aliens constant //binary search for the smallest C where you use //at most K blocks while (Cmin<Cmax) { ll Ctest = (Cmin+Cmax)/2; pii p0 = qry(Ctest); //{cost, # of blocks} if (p0.second<=K) { Cmax = Ctest; } else { Cmin = Ctest+1; } } pii p0 = qry(Cmin); assert(p0.second<=K); pii p1 = qry(Cmin-1); //lower cost, higher # of blocks if (p0.second==K || p0.second==p1.second) { cout << (p0.first+psc[N])<<"\n"; } else { ll fv = p0.first-(K-p0.second)*(p0.first-p1.first)/(p1.second-p0.second); cout << (fv+psc[N]) <<"\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...