#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 2e9;
const int maxn = int(1e6)+5;
struct line
{
line(ll _r,ll _b,int _cnt){r = _r;b = _b;cnt = _cnt;};
line(){};
ll r,b;
int cnt;
ll operator ()(ll x){return r * x + b;};
};
ll inter(line a,line b)
{
if((b.b-a.b)%(a.r-b.r) == 0)
{
return (a.cnt <= b.cnt ? (b.b-a.b)/(a.r-b.r) : (b.b-a.b)/(a.r-b.r)-1);
}
else
{
return (b.b-a.b)/(a.r-b.r);
}
}
vector<pair<int,int>> pr;
vector<line> cl;
int tind = 0;
ll ca[maxn];
ll one_seg[maxn];
ll lseg[maxn];
line lines[maxn];
void add(line l)
{
while(pr.size() && inter(cl.back(),l) < pr.back().first)
{
pr.pop_back();
cl.pop_back();
}
if(!pr.size())
{
pr.push_back({-INF,INF});
cl.push_back(l);
}
else
{
ll t = inter(cl.back(),l);
if(t < INF)
{
pr.back().second = t;
pr.push_back({t+1,INF});
cl.push_back(l);
}
}
}
int get(int x)
{
if(cl.size() == 0)
return -1;
if(cl.back()(x) < cl[tind](x))
{
tind = cl.size()-1;
}
while(tind+1 < cl.size() && pr[tind+1].first <= x)
{
tind++;
}
return tind;
}
pair<ll,int> check(ll lm,int n)
{
pr.clear();
cl.clear();
tind = 0;
pair<ll,int> dp[n];
for(int j = n-1;j >= 0;--j)
{
int u = get(-j);
if(u == -1)
dp[j] = {one_seg[j] + lm,1};
else
{
dp[j] = min(make_pair(one_seg[j] + lm,1),make_pair(cl[u](-j)+lm+ca[j]*j-lseg[j],cl[u].cnt+1));
}
add(line(lines[j].r,lines[j].b + dp[j].first,dp[j].second));
}
return dp[0];
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
int n,k;
cin >> n >> k;
string s;
cin >> s;
ll base_op = 0;
//do s psp
vector<int> apos,bpos;
for(int i = 0;i < 2*n;++i)
{
if(s[i] == 'A')
apos.push_back(i);
else
bpos.push_back(i);
}
string t;
int pnta = 0;
int cbal = 0;
int ac = 0;
for(int i = 0;i < s.size();++i)
{
if(s[i] == 'A')
{
ac++;
if(pnta < n && apos[pnta] == i)
{
pnta++;
cbal ++;
t += 'A';
}
}
else
{
if(cbal > 0)
{
cbal--;
t += 'B';
}
else
{
base_op += apos[pnta]-i+ac-pnta;
pnta++;
t += 'A';
t += 'B';
}
}
}
s = t;
//count one_seg
int pnt = n-1;
pnta = 0;
ll ans= 0;
for(int j = 2*n-1;j >= 0;--j)
{
if(s[j] == 'B')
{
ans += pnta;
one_seg[pnt--] = ans;
}
else
{
pnta++;
}
}
//count lseg and lines
pnt = 0;
ans= 0;
pnta = 0;
for(int j = 0;j < 2*n;++j)
{
if(s[j] == 'B')
{
ca[pnt] = pnta;
lseg[pnt++] = ans;
}
else
{
lines[pnta++] = line(pnta,ans,0);
ans += pnt;
}
}
ll l = 0,r = 1e18;
while(l < r)
{
ll m = (l+r)/2;
if(check(m,n).second > k)
{
l = m+1;
}
else
r = m;
}
cout << check(l,n).first - k * l + base_op << endl;
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |