답안 #906542

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
906542 2024-01-14T12:16:36 Z LucaIlie Chorus (JOI23_chorus) C++17
0 / 100
2 ms 6492 KB
#include <bits/stdc++.h>

using namespace std;

struct DP {
    long long minSwaps;
    int minGroups, maxGroups;

    DP operator + ( DP x ) {
        return { minSwaps + x.minSwaps, minGroups + x.minGroups, maxGroups + x.maxGroups };
    }

    DP operator * ( DP x ) {
        if ( minSwaps < x.minSwaps )
            return *this;
        if ( minSwaps > x.minSwaps )
            return x;
        return { minSwaps, min( minGroups, x.minGroups ), max( maxGroups, x.maxGroups ) };
    }
};

const int MAX_N = 1e6;
const long long INF = 1e18;
int a[MAX_N + 1], countLowerA[MAX_N + 1];
long long sumA[MAX_N + 1], sumLowerA[MAX_N + 1];
DP dp[MAX_N + 1];

struct func {
    long long a, b;
    int valmin, valmax;
};

struct CHT {
    vector<func> funcs;
    vector<long double> start;
    vector<int> stack;

    void init() {
        funcs.clear();
        start.clear();
        stack.clear();
    }

    long double intersection( func f1, func f2 ) {
        long double x = ((long double)f2.b - f1.b) / (f1.a - f2.a);
        return x;
    }

    void addFunction( func f ) {
        int i = funcs.size();

        funcs.push_back( f );
        start.push_back( 0 );
        while ( !stack.empty() && intersection( funcs[i], funcs[stack.back()] ) < start[i] )
            stack.pop_back();

        if ( !stack.empty() )
            start[i] = intersection( funcs[i], funcs[stack.back()] );
        stack.push_back( i );
    }

    DP getMin( long long x ) {
        int l = -1, r = stack.size();
        while ( r - l > 1 ) {
            int mid = (l + r) / 2;
            if ( start[stack[mid]] > x )
                r = mid;
            else
                l = mid;
        }

        DP ans = { INF, 0, 0 };
        for ( int i = r - 1; i >= 0 && start[stack[i]] <= x && (i == stack.size() - 1 || x <= start[stack[i + 1]]); i-- )
            ans = ans * DP{ funcs[stack[i]].a * x + funcs[stack[i]].b, funcs[stack[i]].valmin, funcs[stack[i]].valmax };

        return ans;
    }
} swapFunctions;

void computeDP( int n, long long cost ) {
    swapFunctions.init();
    swapFunctions.addFunction( { 0, 0, 0, 0 } );
    for ( int i = 1; i <= n; i++ ) {
        dp[i] = swapFunctions.getMin( i ) + DP{ i * countLowerA[i] - sumLowerA[i] + cost, 1, 1 };
        swapFunctions.addFunction( func{ -i, dp[i].minSwaps + sumA[i], dp[i].minGroups, dp[i].maxGroups } );
    }
}

int main() {
    int n, k, swaps;

    cin >> n >> k;

    int countB = 0, countA = 0;
    swaps = 0;
    for ( int i = 0; i < 2 * n; i++ ) {
        char ch;
        cin >> ch;
        if ( ch == 'A' )
            countA++;
        else {
            countB++;
            swaps += max( 0, countB - countA );
            a[countB] = max( countA, countB );
            sumA[countB] = sumA[countB - 1] + a[countB];
            countLowerA[a[countB]]++;
            sumLowerA[a[countB]] += a[countB];
        }
    }
    for ( int i = 1; i <= n; i++ ) {
        countLowerA[i] += countLowerA[i - 1];
        sumLowerA[i] += sumLowerA[i - 1];
    }

    long long leftCost = 0, rightCost = 1e12;
    while ( rightCost - leftCost > 1 ) {
        long long cost = (leftCost + rightCost) / 2;

        computeDP( n, cost );

        if ( dp[n].minGroups > k )
            leftCost = cost;
        else
            rightCost = cost;
    }

    computeDP( n, rightCost );
    cout << swaps + dp[n].minSwaps - min( k, dp[n].maxGroups ) * rightCost;

    return 0;
}

Compilation message

chorus.cpp: In member function 'DP CHT::getMin(long long int)':
chorus.cpp:73:67: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   73 |         for ( int i = r - 1; i >= 0 && start[stack[i]] <= x && (i == stack.size() - 1 || x <= start[stack[i + 1]]); i-- )
      |                                                                 ~~^~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6488 KB Output is correct
2 Correct 2 ms 6492 KB Output is correct
3 Correct 2 ms 6492 KB Output is correct
4 Correct 1 ms 6492 KB Output is correct
5 Correct 1 ms 6492 KB Output is correct
6 Correct 1 ms 6488 KB Output is correct
7 Correct 2 ms 6492 KB Output is correct
8 Incorrect 2 ms 6492 KB Output isn't correct
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6488 KB Output is correct
2 Correct 2 ms 6492 KB Output is correct
3 Correct 2 ms 6492 KB Output is correct
4 Correct 1 ms 6492 KB Output is correct
5 Correct 1 ms 6492 KB Output is correct
6 Correct 1 ms 6488 KB Output is correct
7 Correct 2 ms 6492 KB Output is correct
8 Incorrect 2 ms 6492 KB Output isn't correct
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6488 KB Output is correct
2 Correct 2 ms 6492 KB Output is correct
3 Correct 2 ms 6492 KB Output is correct
4 Correct 1 ms 6492 KB Output is correct
5 Correct 1 ms 6492 KB Output is correct
6 Correct 1 ms 6488 KB Output is correct
7 Correct 2 ms 6492 KB Output is correct
8 Incorrect 2 ms 6492 KB Output isn't correct
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6488 KB Output is correct
2 Correct 2 ms 6492 KB Output is correct
3 Correct 2 ms 6492 KB Output is correct
4 Correct 1 ms 6492 KB Output is correct
5 Correct 1 ms 6492 KB Output is correct
6 Correct 1 ms 6488 KB Output is correct
7 Correct 2 ms 6492 KB Output is correct
8 Incorrect 2 ms 6492 KB Output isn't correct
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6488 KB Output is correct
2 Correct 2 ms 6492 KB Output is correct
3 Correct 2 ms 6492 KB Output is correct
4 Correct 1 ms 6492 KB Output is correct
5 Correct 1 ms 6492 KB Output is correct
6 Correct 1 ms 6488 KB Output is correct
7 Correct 2 ms 6492 KB Output is correct
8 Incorrect 2 ms 6492 KB Output isn't correct
9 Halted 0 ms 0 KB -