Official

D - Flip to Gather Editorial by en_translator


Let \(A_i=(\)the number of 0 in \(S_1,S_2,\ldots,S_i)\) and \(B_i=(\)the number of 1 in \(S_1,S_2,\ldots,S_i)\). (Define \(A_0=B_0=0\).)

Given a pair of integers \((l,r)\) \((1 \leq l \leq r \leq N+1)\), let us consider how many operations are needed so that \(S_i=\) 1 if and only if \(l \leq i < r\).

First, we need to operate as many times as the number of indices \(i\) \((1 \leq i \leq N)\) with \(l \leq i <r\) such that \(S_i=\) 0. This count is represented as \(A_{r-1}-A_{l-1}\). Moreover, we further need to operate as many times as the number of indices \(i\) \((1 \leq i \leq N)\) with \(i<l\) or \(r \leq i\) such that \(S_i=\) 1. This count is represented as \(B_N-(B_{r-1}-B_{l-1})\). Conversely, we also see that \(B_N+A_{r-1}-B_{r-1}-A_{l-1}+B_{l-1}\) operations are sufficient.

Therefore, it is sufficient to find the minimum \(A_{r-1}-B_{r-1}-A_{l-1}+B_{l-1}\) over all possible integer pairs \((l,r)\) \((1 \leq l \leq r \leq N+1)\). If we define \(C_i=A_i-B_i\), the count can be written as \(C_{r-1}-C_{l-1}\). The minimum value of \(C_{r-1}-C_{l-1}\) for a sequence \(C\) can be found as \(\displaystyle \min_{1 \leq l \leq r \leq N+1} C_{r-1}-C_{l-1}=\min_{1 \leq r \leq N+1} (C_{r-1}-\max_{1 \leq l \leq r}C_{l-1})\), which allows us to scan \(C\) for \(r=1,2,\ldots,N+1\) in order while maintaining the tentative maximum value of \(C\) to find the sought minimum value in a total of \(\mathrm{O}(N)\) time.

Hence, the problem itself can also be solved in a total of \(\mathrm{O}(N)\) time.

Sample code (C++)

#include <bits/stdc++.h>
using namespace std;
void solve() {
    int n;
    cin >> n;
    string s;
    cin >> s;
    vector<int> c(n + 1);
    for (int i = 0; i < n; ++i) {
        c[i + 1] = c[i] + (s[i] == '0' ? 1 : -1);
    }
    int sum = count(s.begin(), s.end(), '1');
    int ma = 0;
    int res = 0;
    for (int i = 0; i <= n; ++i) {
        res = min(res, c[i] - ma);
        ma = max(ma, c[i]);
    }
    cout << sum + res << endl;
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
}

posted:
last update: