제출 #1355981

#제출 시각아이디문제언어결과실행 시간메모리
1355981alexddChorus (JOI23_chorus)C++20
0 / 100
0 ms344 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int INF = 1e18;
const int MAXN = 1e6 + 5;

typedef long double ld;
struct line
{
    int m, b;
    int eval(int x) {return m * x + b;}
};
ld interx(line a, line b)
{
    return ((ld)b.b - (ld)a.b) / ((ld)a.m - (ld)b.m);
}

int n,k;
string s;
int pozb[MAXN];



int dp[MAXN], cnt_songs[MAXN];

int auxdp[MAXN];

pair<int, int> solve(int coef)//{{rez_coef, {nr_swaps, cnt_songs}}
{
    /*dp[0] = 0;
    cnt_songs[0] = 0;
    int lim = 0;
    int balance = 0;
    for(int i=1;i<=n;i++)
    {
        while(lim + 1 <= i && pozb[lim + 1] < i)
            lim++;

        dp[i] = INF;
        cnt_songs[i] = -1;

        auxdp[i-1] = dp[i-1] + coef - balance;
        balance += max(0LL, (i-1) - pozb[i]);
        for(int x=0;x<lim;x++)
            auxdp[x] += lim - x;

        for(int x=i-1;x>=0;x--)
        {
            if(auxdp[x] + balance < dp[i])
            {
                dp[i] = auxdp[x] + balance;
                cnt_songs[i] = cnt_songs[x] + 1;
            }
        }
    }*/


    int lim = 0, balance = 0, balance_hull = 0;
    deque<line> hull;

    dp[0] = 0;
    cnt_songs[0] = 0;
    for(int i=1;i<=n;i++)
    {

        dp[i] = INF;
        cnt_songs[i] = -1;

        auxdp[i-1] = dp[i-1] + coef - balance;
        balance += max(0LL, (i-1) - pozb[i]);


        while(lim + 1 <= i && pozb[lim + 1] < i)
        {
            hull.push_back({-lim, auxdp[lim] + lim * (i-1) - balance_hull});
            lim++;
        }

        //for(int x=0;x<lim;x++)
           // auxdp[x] += lim - x;

        balance_hull += lim;

        for(line l:hull)
        {
            int cv = l.eval(i) + balance + balance_hull;
            if(cv < dp[i])
            {
                dp[i] = cv;
                cnt_songs[i] = cnt_songs[-l.m] + 1;
            }
        }

        for(int x=i-1;x>=lim;x--)
        {
            if(auxdp[x] + balance < dp[i])
            {
                dp[i] = auxdp[x] + balance;
                cnt_songs[i] = cnt_songs[x] + 1;
            }
        }
    }

    return {dp[n], cnt_songs[n]};
}

signed main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n>>k>>s;
    assert(s.size() == 2 * n);
    int cnta = 0, cntb = 0;
    for(int i=0;i<2*n;i++)
    {
        if(s[i] == 'A')
        {
            cnta++;
        }
        else
        {
            cntb++;
            pozb[cntb] = cnta;
        }
    }

    assert(cnta == n && cntb == n);


    int st = 0, dr = 1e9, ans = -1;
    while(st <= dr)
    {
        int mij = (st + dr) / 2;
        auto x = solve(mij);

        if(x.second >= k)
        {
            ans = mij;
            st = mij + 1;
        }
        else
        {
            dr = mij - 1;
        }
    }
    assert(ans != -1);

    auto x = solve(ans);
    cout<<x.first - k * ans;
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…