Submission #906541

#TimeUsernameProblemLanguageResultExecution timeMemory
906541LucaIlieChorus (JOI23_chorus)C++17
0 / 100
2 ms6492 KiB
#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; i-- ) { if ( start[stack[i]] <= x && (i == stack.size() - 1 || x <= start[stack[i + 1]]) ) 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 (stderr)

chorus.cpp: In member function 'DP CHT::getMin(long long int)':
chorus.cpp:74:45: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   74 |             if ( start[stack[i]] <= x && (i == stack.size() - 1 || x <= start[stack[i + 1]]) )
      |                                           ~~^~~~~~~~~~~~~~~~~~~
#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...