Table of Contents

ExplanationImplementation

Official Analysis (C++)

Explanation

First, notice that sequences OWOW and WOWO can be transformed into a CC. As an example, we transform OWOW to CWWCWW and then simplify into CC. We can also rearrange any two adjacent characters, like COCO to OCOC. As an example, we transform COCO to OWWCOWWC and then simplify to OCOC.

Since we can freely swap characters in a substring, only the frequency of each character is relevant in answering a query.

Let CC, WW, and OO be the frequency of their respective characters in the queried subarray. We can compute these values with prefix sums.

Notice that if C+WC + W or C+OC + O are even, the answer must be false, because we can't simplify the substring into a single CC without OO or WW characters remaining. This is because the parity of C+WC + W or C+OC + O is always constant, beacuse by performing the expansion or deletion operation, we can never change the parity. (For example, CWCWCWCW -> CWCW or CWCW -> COCCOC, both of which hold the same parity of C + W).

To prove that the substring is valid when C+WC + W is odd and C+OC + O is odd, we can first notice that when these two conditions hold, W+OW + O is even.

Next, we simplify WW and OO by removing all duplicate pairs. One possibility is that we will be left with W=0W = 0 and O=0O = 0, meaning that CC was odd, and thus it can easily be simplified into one CC character.

Otherwise, we will be left with W=1W = 1 and O=1O = 1, meaning that CC was even. By combining the WCWC pair into a singular CC, we will be left with an odd amount of CC, which can be simplified into one CC character.

So, to answer a query, we check if C+WC+W and C+OC+O are both odd. Calculating these values can be done using prefix sums.

Implementation

Time Complexity: O(N)\mathcal{O}(N)

C++

#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
// Calculate prefix array for each character
vector<array<int, 3>> a(s.size() + 1);
for (int i = 1; i <= s.size(); i++) {

Python

s = input()
n = len(s)
# Calculate prefix array for each character
a = [[0, 0, 0] for _ in range(n + 1)]
for i, ch in enumerate(s, 1):
a[i][0] = a[i - 1][0] + (ch == "C")
a[i][1] = a[i - 1][1] + (ch == "O")
a[i][2] = a[i - 1][2] + (ch == "W")

Java

import java.io.*;
import java.util.StringTokenizer;
public class COWOperations {
public static void main(String[] args) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(System.out);
String s = r.readLine();
// Calculate the prefix array for each character

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!