Official

C - Range Search Query Editorial by en_translator Editorial for printing


The key to this problem is that precalculating the positions where \(T\) occur helps processing the queries fast.

Let \(|S| = N\) and \(|T| = M\).
For each \(i=1,2,\dots,N\), define \(A_i\) as follows:

\[ A_i = \begin{cases} 1 & \text{If the length-}M\text{ string starting from the }i\text{-th character of }S\text{ coincides with }T \\ 0 & \text{otherwise.} \end{cases} \]

Note that \(A_i = 0\) for \(i+M-1 \gt N\).
Since \(M\) is small, calculating \(A_1, A_2, \dots\) and \(A_N\) can be done in \(\mathrm{O}(NM)\).

Additionally, define the prefix sums \(P_0, P_1, \dots, P_N\) as:

\[P_0 = 0, P_i = \sum_{j=1}^i A_j.\]

The prefix-sum table \(P\) allows us to find the number of occurrences of \(T\) starting from a position between the segment \([l, r]\) as

\[P_r - P_{l-1}.\]

How can we use this \(P\) to answer the queries? Given \(L\) and \(R\) in a query, branch by which of \(M\) and the length of the queried range is larger.

(1) If \(R - L + 1 \lt M\)

If \(R - L + 1 \lt M\), the substring formed by the \(L\)-th through \(R\)-th characters of \(S\) has a length strictly less than \(M\), so it never contains \(T\). Thus, the answer is No.

(2) If \(R - L + 1 \geq M\)

If \(R - L + 1 \geq M\), the substring formed by the \(L\)-th through \(R\)-th characters has a length at least \(M\).
Since any length-\(M\) characters whose right end is the \(R\)-th character of \(S\) has the \((R - M + 1)\)-th character of \(S\) as its left end, the starting position \(i\) that needs inspected is

\[ L \leq i \leq R - M + 1.\]

Hence, the answer is Yes if \(P_{R-M+1} - P_{L-1} \gt 0\), and No otherwise.

By implementing this algorithm, the problem can be solved in \(\mathrm{O}(|S| |T|)\) time, which is fast enough.

posted:
last update: