제출 #868494

#제출 시각아이디문제언어결과실행 시간메모리
868494chonkaChorus (JOI23_chorus)C++17
40 / 100
55 ms8996 KiB
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef unsigned long long ull ;
typedef pair < int , int > pii ;
typedef vector < int > vi ;
#define fi first
#define se second
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()

const int MAXN = 1e6 + 7 ;

int n , k ;
int a[ MAXN ] , b[ MAXN ] ;
int lw[ MAXN ] , ori[ MAXN ] ;
ll pref[ MAXN ] ;

ll prec[ 5005 ][ 5005 ] ;

inline ll calc ( int l , int r ) {
    if ( l > r ) { return 0 ; }
    if ( r <= ori[ l ] ) { return 0 ; }
    int aux_st = max ( ori[ l ] , l - 1 ) ;
    return ( pref[ r ] - pref[ aux_st ] ) - 1LL * ( r - aux_st ) * ( l - 1 ) ;
}

ll dp[ MAXN ] ;
int ctr[ MAXN ] ;


int get_fst ( int x , int y ) {
    int l , r , mid ;
    l = max ( x , y ) , r = n ;
    if ( make_pair ( dp[ x ] + calc ( x + 1 , n ) , ctr[ x ] ) < make_pair ( dp[ y ] + calc ( y + 1 , n ) , ctr[ y ] ) ) { return n + 1 ; }
    while ( l < r ) {
        mid = ( l + r ) / 2 ;
        if ( make_pair ( dp[ x ] + calc ( x + 1 , mid ) , ctr[ x ] ) < make_pair ( dp[ y ] + calc ( y + 1 , mid ) , ctr[ y ] ) ) { l = mid + 1 ; }
        else { r = mid ; }
    }
    return l ;
}


pair < ll , int > f ( ll sr ) {
    deque < int > q ;
    q.push_front ( 0 ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        while ( (int)q.size ( ) >= 2 && get_fst ( q[ 0 ] , q[ 1 ] ) <= i ) {
            q.pop_front ( ) ;
        }
        while ( (int)q.size ( ) >= 3 && get_fst ( q[ 0 ] , q[ 1 ] ) >= get_fst ( q[ 1 ] , q[ 2 ] ) ) {
            int x = q[ 0 ] ;
            q.pop_front ( ) ; q.pop_front ( ) ;
            q.push_front ( x ) ;
        }
        int x = q.front ( ) ;
        dp[ i ] = dp[ x ] + calc ( x + 1 , i ) + sr ;
        ctr[ i ] = ctr[ x ] + 1 ;
        while ( (int)q.size ( ) >= 1 && get_fst ( q.back ( ) , i ) <= i ) { q.pop_back ( ) ; }
        q.push_back ( i ) ;
        /**
        dp[ i ] = calc ( 1 , i ) + sr , ctr[ i ] = 1 ;
        for ( int j = 1 ; j < i ; ++ j ) {
            auto aux = make_pair ( dp[ j ] + calc ( j + 1 , i ) + sr , ctr[ j ] + 1 ) ;
            if ( make_pair ( dp[ i ] , ctr[ i ] ) > aux ) {
                dp[ i ] = aux.fi , ctr[ i ] = aux.se ;
            }
        }
        if ( sr == 0 && dp[ i ] == 0 ) {
            printf ( "%d --> %lld %d\n" , i , dp[ i ] , ctr[ i ] ) ;
        }
        **/
    }
    return { dp[ n ] , ctr[ n ] } ;
}

void solve ( ) {
    cin >> n >> k ;
    string s ; cin >> s ;
    int pos1 = 0 , pos2 = 0 ;
    for ( int i = 1 ; i <= 2 * n ; ++ i ) {
        if ( s[ i - 1 ] == 'A' ) { a[ ++ pos1 ] = i ; }
        else { b[ ++ pos2 ] = i ; }
    }
    int tp = 0 ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        while ( tp < n && b[ tp + 1 ] < a[ i ] ) { ++ tp ; }
        lw[ i ] = tp ;
        pref[ i ] = pref[ i - 1 ] + lw[ i ] ;
    }
    pref[ n + 1 ] = pref[ n ] ;
    tp = 0 ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        while ( tp < n && lw[ tp + 1 ] < i ) { ++ tp ; }
        ori[ i ] = tp ;
    }
    /**
    for ( int i = 1 ; i <= n ; ++ i ) {
        int wh = i ;
        for ( int j = i ; j <= n ; ++ j ) {
            while ( wh <= n && a[ j ] > b[ wh ] ) { ++ wh ; }
            prec[ i ][ j ] = prec[ i ][ j - 1 ] + wh - i ;
            if ( prec[ i ][ j ] != calc ( i , j ) ) {
                printf ( "what %d %d %lld %lld\n" , i , j , prec[ i ][ j ] , calc ( i , j ) ) ;
                return ;
            }
        }
    }
    **/
    ll l , r , mid ;
    l = -1 , r = ( 1LL << 41 ) ;
    while ( l < r ) {
        mid = ( l + r ) / 2 ;
        auto [ ret , cnt ] = f ( mid ) ;
        if ( cnt > k ) { l = mid + 1 ; }
        else { 
            if ( mid == r ) { break ; }
            r = mid ;
        }
    }
    auto [ ret , cnt ] = f ( r ) ;
    cout << ret - k * r << "\n" ;
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    int t = 1 ; // cin >> t ;
    while ( t -- ) { solve ( ) ; }
    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...