제출 #1179014

#제출 시각아이디문제언어결과실행 시간메모리
1179014ace5Chorus (JOI23_chorus)C++20
100 / 100
1872 ms110384 KiB
#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)
{
    assert(a.r > b.r);
    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
    {
        if(b.b < a.b)
            return (b.b-a.b-(a.r-b.r)+1)/(a.r-b.r);
        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)
{
    //  cout << x << ' ' << tind << "!!!\n";
    // if(cl.size())
    // {
    //     cout << cl[tind].r << ' ' << cl[tind].b << endl;
    // }
    if(cl.size() == 0)
        return -1;
    if(tind >= cl.size())
        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)
{
    // cout << "! " << lm << endl; 
    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
        {
            //  cout << cl[u].r << ' ' << cl[u].b << ' ' << cl[u].cnt << ' ' << lm+ca[j]*j-lseg[j] << endl;
            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));
        }
        //  cout << lines[j].r << ' ' << lines[j].b + dp[j].first << endl;
        add(line(lines[j].r,lines[j].b + dp[j].first,dp[j].second));
        // cout << one_seg[j] << ' ' << dp[j].first << ' ' << dp[j].second << endl; 
    }
    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;
    // cout << base_op << ' ' << t << endl;
    //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')
        {
           // cout << j << endl;
            ans += pnta;
            // if(pnt == n-1)
            // {
            //     cout << ans << "??\n";
            // }
            one_seg[pnt--] = ans;
        }
        else
        {
            pnta++;
        }
    }
   // cout << one_seg[n-1] << "!!!\n";
    //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 << base_op << ' ';
    cout << check(l,n).first - k * l + base_op << endl;
    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...