Official Editorial

Explanation

To solve this problem, we can use brute force and check every possible length of r0r_0. Let c0c_0 and c1c_1 denote the number of zeros and ones in ss, respectively. The length of r1r_1 can be determined by sc0r0c1\frac{|s| - c_0 \cdot |r_0|}{c_1}. If this length is not an integer, then this r0r_0 is invalid and no further check is required for it.

For each possible length of r0r_0, we want to check if the given pattern in ss matches the received signal tt. Let the hash of rir_i be hih_i. By pre-calculating the prefix sums of the hashes for tt, we can iterate through ss and check for each character sis_i in ss if the hash of its corresponding part in tt equals hsih_{s_i}. This corresponding part in tt can be located if we use a pointer tjt_j and increase it by ri|r_i| every time we checked a character from ss. At the end, if all hashes match, then we have found a possible r0r_0. Otherwise, if there is a mismatch at any point, we can terminate and go for the next possible length of r0r_0.

Time Complexity

We first note that checking for a possible r0r_0 can be done in O(s)\mathcal{O}(|s|) since for each character sis_i in ss, we can get the hash of its corresponding substring in tt in O(1)\mathcal{O}(1), given O(s)\mathcal{O}(|s|) pre-processing to calculate the prefix sums of the hashes.

Then, let's determine that number of possible lengths of r0r_0. Without loss of generality, suppose c0c1    c0s/2c_0 \geq c_1 \implies c_0 \geq |s| / 2. As r0|r_0| and r1|r_1| are strict positive, r0|r_0| must be less or equal to t/c0\lfloor |t| / c_0 \rfloor.

Therefore, the overall time complexity is O(s(t/c0))O(st(2/s))=O(t)\mathcal{O} (|s| \cdot (|t| / c_0)) \leq \mathcal{O} (|s| \cdot |t| \cdot (2 / |s|)) = \mathcal{O} (|t|).

Implementation

C++

#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long int;
ull m = 1e9 + 9;
ull base = 9973;
// Hashes and powers start with 1
vector<ull> rolling_hash;
vector<ull> powers;

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!