BackmediumStringsMicrosoftAdobe

Bounded Range Segment Evaluator 4 Solution

Problem Statement

You are given a string S of length N (1 ≤ N ≤ 10^5) composed of lowercase English letters. Following the string, you receive Q queries (1 ≤ Q ≤ 10^5). Each query supplies two integers L and R (1 ≤ L ≤ R ≤ N) and a pattern string P. For every query, determine whether P can be obtained as a subsequence of the substring S[L..R] (the portion of S from position L to R, inclusive). Output "YES" if such a subsequence exists, otherwise output "NO". The total length of all pattern strings across all queries does not exceed 10^6.

Input format

  • Line 1: the string S.
  • Line 2: the integer Q.
  • Next Q lines: each line contains L R P separated by spaces.

Output format For each query, print a single line containing either "YES" or "NO".

The task requires an algorithm that processes all queries efficiently, respecting the stated time limits.

Example 1
Input
abacaba 3 1 7 aba 2 5 ac 3 3 b
Output
YES YES NO

Explanation: Query 1: The substring S[1..7] is "abacaba". The pattern "aba" appears as a subsequence (positions 1,3,5). Query 2: Substring S[2..5] is "baca"; "ac" is a subsequence (positions 3,4). Query 3: Substring S[3..3] is "a"; the pattern "b" cannot be formed, so the answer is NO.

Example 2
Input
xyzabc 2 1 3 xy 4 6 cba
Output
YES NO

Explanation: Query 1: Substring S[1..3] is "xyz"; "xy" is a subsequence (positions 1,2). Query 2: Substring S[4..6] is "abc"; the pattern "cba" cannot be formed in order, hence NO.

Example 3
Input
aaaaa 1 2 4 aaa
Output
YES

Explanation: Substring S[2..4] is "aaa". The pattern "aaa" matches exactly, so the answer is YES.

Constraints

  • 1 ≤ N ≤ 10^5
  • 1 ≤ Q ≤ 10^5
  • 1 ≤ L ≤ R ≤ N
  • The sum of |P| over all queries ≤ 10^6
  • S and all P consist only of lowercase English letters
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Bounded Range Segment Evaluator 4 — Problem Statement & Solution Guide

StringsMediumSubsequence Verification
TimeO(N·Σ) preprocessing + O(total |P|) query time, where Σ=26; effectively O(N·26 + Σ|P|) ≈ O(N + total |P|)
|
SpaceO(N·Σ) integers for the next table (≈ 2.6 million for Σ=26) or O(N) for position vectors

Problem Description

You are given a string **S** of length **N** (1 ≤ N ≤ 10^5) composed of lowercase English letters. Following the string, you receive **Q** queries (1 ≤ Q ≤ 10^5). Each query supplies two integers **L** and **R** (1 ≤ L ≤ R ≤ N) and a pattern string **P**. For every query, determine whether **P** can be obtained as a subsequence of the substring **S[L..R]** (the portion of **S** from position **L** to **R**, inclusive). Output "YES" if such a subsequence exists, otherwise output "NO". The total length of all pattern strings across all queries does not exceed 10^6.

**Input format**

- Line 1: the string **S**.

- Line 2: the integer **Q**.

- Next **Q** lines: each line contains **L R P** separated by spaces.

**Output format**

For each query, print a single line containing either "YES" or "NO".

The task requires an algorithm that processes all queries efficiently, respecting the stated time limits.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Bounded Range Segment Evaluator 4"

medium

WHY DOES IT MATTER?

The “next‑occurrence” pattern transforms a potentially quadratic scan into a series of constant‑time jumps, enabling us to answer massive numbers of subsequence queries on a static string efficiently. It is a core technique in string algorithms, automata simulation, and range‑restricted matching.

OPTIMIZATION CHALLENGE

The key insight is to decouple the heavy work (finding next positions) from each query by doing it once in a backward pass over S. This reduces per‑query work from scanning the whole substring to merely walking through the pattern, achieving linear time in |P| regardless of substring length.

REAL-WORLD CONNECTION

Think of a distributed log system where you need to verify whether a sequence of events occurred within a specific time window. Pre‑indexing timestamps for each event type lets you jump directly to the next relevant entry, just like the next‑position table jumps to the next character.

When coding, build the next‑position table as a 2‑D int array of size (N+2)×26, fill it backwards, and use a sentinel value (N+1) to denote “no occurrence”. During a query, early‑exit as soon as the pointer exceeds R – this saves time on long patterns that already fail.

COMPLEXITY AT A GLANCE

⏱ Time:O(N·Σ) preprocessing + O(total |P|) query time, where Σ=26; effectively O(N·26 + Σ|P|) ≈ O(N + total |P|)
💾 Space:O(N·Σ) integers for the next table (≈ 2.6 million for Σ=26) or O(N) for position vectors

Core Theory — Why This Approach?

The problem asks whether a pattern string P appears as a subsequence inside an arbitrary substring S[L..R]. A subsequence respects order but not contiguity, so we must locate each character of P one after another within the bounded interval. A naïve scan for every query would restart from L and walk through S[L..R] character‑by‑character, yielding O(N·Q) time in the worst case – far beyond the 10^5 limits. The optimal paradigm is to preprocess the original string once, building a data structure that can jump to the next occurrence of any alphabet letter in O(1) or O(log N) time. Two classic techniques fit: (1) a 26‑column “next‑position” table where next[i][c] stores the smallest index ≥ i where character c appears, and (2) per‑character position vectors with binary search. Both reduce each query to a linear scan over |P|, independent of the substring length, turning the overall complexity into O(total |P| + N·alphabet). This preprocessing‑query separation is the hallmark of offline string‑matching problems such as “multiple subsequence queries” and is essential for scaling to 10^5 queries.

When using the next‑position table, we fill it backwards: for i from N down to 1, copy next[i+1] and then set next[i][S[i]] = i. Any lookup for the next occurrence of a character after a current pointer becomes a constant‑time array access. The query algorithm then iterates through P, repeatedly moving the pointer via next[pos][c] and checking that the returned index does not exceed R. If at any step the pointer jumps outside the interval, the answer is false; otherwise true. This method avoids repeated scans of the same region and guarantees worst‑case O(|P|) per query, which is optimal because we must at least read each character of P.

The alternative binary‑search on position vectors also respects the same asymptotic bound: each character lookup costs O(log N) but is often simpler to implement when memory is tight. Both approaches illustrate the broader algorithmic theme of “pre‑compute next occurrence” (also known as the “jump table” or “successor array”) that appears in problems like string subsequence checking, automaton simulation, and online pattern matching.

Interview Questions on This Problem

Q1How would you modify the solution if the alphabet size were up to 10^5 (e.g., Unicode characters) instead of 26?

Instead of a dense next‑position table, store for each character a sorted list of its positions in S. For each query, iterate through P and binary‑search the list to find the first occurrence ≥ current pointer and ≤ R. This keeps preprocessing O(N) and each lookup O(log N), yielding O(|P|·log N) per query, which is acceptable for large alphabets.

Q2Can you answer the queries online (i.e., without knowing all queries beforehand) while still achieving O(|P|) per query?

Yes. The next‑position table or the per‑character position vectors are built solely from S, which is known before any query arrives. Since they are static, each query can be answered independently in O(|P|) (or O(|P|·log N) with binary search) without any offline reordering.

Q3What would be the impact on time and space complexity if the total length of all pattern strings across queries summed to 10^7?

The preprocessing cost remains O(N·alphabet) or O(N) for position vectors, unchanged. The query cost becomes O(total |P|) = O(10^7) for the constant‑time next table, which is still feasible. Memory stays O(N·alphabet) ≈ 2.6 million integers for 26 letters, or O(N) for vectors, both well within limits.

Examples

Example 1

Input

abacaba
3
1 7 aba
2 5 ac
3 3 b

Output

YES
YES
NO

Explanation: Query 1: The substring S[1..7] is "abacaba". The pattern "aba" appears as a subsequence (positions 1,3,5). Query 2: Substring S[2..5] is "baca"; "ac" is a subsequence (positions 3,4). Query 3: Substring S[3..3] is "a"; the pattern "b" cannot be formed, so the answer is NO.

Example 2

Input

xyzabc
2
1 3 xy
4 6 cba

Output

YES
NO

Explanation: Query 1: Substring S[1..3] is "xyz"; "xy" is a subsequence (positions 1,2). Query 2: Substring S[4..6] is "abc"; the pattern "cba" cannot be formed in order, hence NO.

Example 3

Input

aaaaa
1
2 4 aaa

Output

YES

Explanation: Substring S[2..4] is "aaa". The pattern "aaa" matches exactly, so the answer is YES.

Constraints

  • 1 ≤ N ≤ 10^5
  • 1 ≤ Q ≤ 10^5
  • 1 ≤ L ≤ R ≤ N
  • The sum of |P| over all queries ≤ 10^6
  • S and all P consist only of lowercase English letters

Optimal Approach & Strategy

Preprocess S to store the next occurrence of every letter at each index (or position vectors). Then answer each query by walking through P, jumping via the precomputed data, and checking that we never exceed R.

Brute Force Approach

For each query, scan S[L..R] left‑to‑right while matching characters of P one by one; if you finish P you return true, otherwise false.

Verified Code Solutions

JavaScript Solution
Time: O(N·Σ) preprocessing + O(total |P|) query time, where Σ=26; effectively O(N·26 + Σ|P|) ≈ O(N + total |P|)
function solution(nums) {
   let sum = 0;
   for (let num of nums) {
       sum += num;
   }
   return sum;
}

Asked in Top Tech Interviews

MicrosoftAdobe

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.