def min_operations_to_good_string(N, S): a = [1 if c == '1' else -1 for c in S] psum = [0] * (N + 1) for i in range(N): psum[i + 1] = psum[i] + a[i] Z = [i + 1 for i, c in enumerate(S) if c == '0'] def can_make_good(K): # 先頭からK個の0を1に変える flip = [0] * (N + 2) for idx in range(K): flip[Z[idx]] += 1 # 累積和でA[i]を構築 cnt = 0 A = [0] * (N + 1) for i in range(N + 1): if i > 0: cnt += flip[i] A[i] = psum[i] + 2 * cnt min_prefix = A[0] for i in range(2, N + 1): if A[i] < min_prefix: return False if A[i - 1] < min_prefix: min_prefix = A[i - 1] return True left, right = 0, len(Z) while left < right: mid = (left + right) // 2 if can_make_good(mid): right = mid else: left = mid + 1 return left