BackhardBinary SearchAtlassianMorgan Stanley

Lazy Segment Query Evaluator 4 Solution

Problem Statement

You are given an array A of N integers. You must answer Q queries. Each query supplies three integers l, r, and k (1‑based indices). For the subarray A[l..r] (inclusive), determine the k‑th smallest element. If k is larger than the number of elements in the subarray, output -1. The task is to process all queries efficiently; a common approach is to perform a binary search over the value domain for each query, using a data structure that can count how many elements in a given range are less than or equal to a candidate value. This technique is known as Binary Search on the Answer Matrix.

Example 1
Input
5 3 1 5 2 6 3 1 5 2 2 4 3 3 3 1
Output
2 6 2

Explanation: Query 1: subarray [1,5] contains {1,5,2,6,3}. Sorted: {1,2,3,5,6}. The 2nd smallest is 2. Query 2: subarray [2,4] contains {5,2,6}. Sorted: {2,5,6}. The 3rd smallest is 6. Query 3: subarray [3,3] contains {2}. The 1st smallest is 2.

Example 2
Input
4 2 10 20 30 40 1 4 4 2 3 1
Output
40 20

Explanation: Query 1: subarray [1,4] is {10,20,30,40}. Sorted: {10,20,30,40}. The 4th smallest is 40. Query 2: subarray [2,3] is {20,30}. Sorted: {20,30}. The 1st smallest is 20.

Example 3
Input
6 3 5 1 4 2 3 6 1 6 3 2 5 2 4 6 5
Output
3 2 -1

Explanation: Query 1: subarray [1,6] is {5,1,4,2,3,6}. Sorted: {1,2,3,4,5,6}. The 3rd smallest is 3. Query 2: subarray [2,5] is {1,4,2,3}. Sorted: {1,2,3,4}. The 2nd smallest is 2. Query 3: subarray [4,6] has only 3 elements, but k=5, so the answer is -1.

Constraints

  • 1 <= N <= 100000
  • 1 <= Q <= 100000
  • 1 <= l <= r <= N
  • -10^9 <= A[i] <= 10^9
  • 1 <= k <= r - l + 1 (if k exceeds subarray length, output -1)
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

Lazy Segment Query Evaluator 4 — Problem Statement & Solution Guide

Binary SearchHardBinary Search on Answer Matrix
TimeO((N + Q) * log N) for persistent tree (building O(N log N) + query O(log N) each) or O((N + Q) * log N * log V) for parallel binary search
|
SpaceO(N * log N) for persistent segment tree; O(N) extra for Fenwick in parallel binary search

Problem Description

You are given an array A of N integers. You must answer Q queries. Each query supplies three integers l, r, and k (1‑based indices). For the subarray A[l..r] (inclusive), determine the k‑th smallest element. If k is larger than the number of elements in the subarray, output -1. The task is to process all queries efficiently; a common approach is to perform a binary search over the value domain for each query, using a data structure that can count how many elements in a given range are less than or equal to a candidate value. This technique is known as Binary Search on the Answer Matrix.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Lazy Segment Query Evaluator 4"

hard

WHY DOES IT MATTER?

Order‑statistic queries are a classic example of combining search over a value domain with fast range counting. Mastering this pattern unlocks solutions for many “k‑th” or “median” problems that appear in databases, analytics, and competitive programming.

OPTIMIZATION CHALLENGE

The breakthrough is recognizing that the answer can be found without enumerating the subarray: by pre‑processing cumulative frequency information (persistent tree or BIT) we turn a linear scan into a logarithmic count, and then binary‑search over values reduces the problem to O(log V) such counts.

REAL-WORLD CONNECTION

Think of a distributed log‑aggregation system where each node stores timestamps of events. To find the k‑th earliest event in a time window, you binary‑search the timestamp space while each node quickly reports how many events fall before a candidate timestamp, analogous to the range‑count structure used here.

When coding under interview pressure, first implement the persistent segment tree skeleton – building versions while inserting each array element – then focus on the query walk; this isolates bugs and avoids the more intricate bookkeeping of parallel binary search.

COMPLEXITY AT A GLANCE

⏱ Time:O((N + Q) * log N) for persistent tree (building O(N log N) + query O(log N) each) or O((N + Q) * log N * log V) for parallel binary search
💾 Space:O(N * log N) for persistent segment tree; O(N) extra for Fenwick in parallel binary search

Core Theory — Why This Approach?

The k‑th order statistic query on a static array can be reduced to a series of range‑count queries: given a candidate value X, we need to know how many elements ≤ X lie in A[l..r]. If that count is ≥ k, the answer lies at most X; otherwise it is larger. By binary‑searching over the sorted list of distinct values and answering each count query in O(log N) we achieve O(log V·log N) per query, where V is the value domain size. Naïve scanning of the subarray for each query costs O(N·Q) and quickly exceeds limits for N, Q up to 2·10⁵. The optimal paradigm combines a value‑domain binary search with a data structure that supports fast prefix‑frequency queries – either a persistent segment tree (also called Chairman Tree) built over the value axis, or a Fenwick tree used in a parallel‑binary‑search (offline) framework. Both structures turn the problem into O(log N) per count, yielding overall O((N+Q)·log N) time and O(N·log N) memory for persistence, or O((N+Q)·log N·log V) for the parallel approach.

Interview Questions on This Problem

Q1How would you answer k‑th smallest queries on a static array in O(log N) per query?

Build a persistent segment tree where each version corresponds to the prefix of the array; each node stores the count of elements in its value range. To answer a query (l, r, k), walk the two versions (r and l‑1) simultaneously, descending the tree based on the difference in counts to locate the k‑th smallest in O(log N).

Q2Explain the parallel binary search technique for offline k‑th order statistic queries and its time complexity.

Collect all queries and perform a binary search over the sorted distinct values simultaneously. In each iteration, group queries by their current mid value, update a Fenwick tree with array elements ≤ mid, and compute the count in each query's range. Based on the count, move the binary search bounds. Each iteration costs O((N+Q)·log N) and there are O(log V) iterations, giving O((N+Q)·log N·log V).

Q3Why can a merge‑sort tree answer k‑th smallest queries in O(log² N) and when would you prefer it over a persistent tree?

A merge‑sort tree stores a sorted vector at each segment‑tree node. To find the k‑th smallest, we binary‑search the answer value and, for each candidate, query O(log N) nodes to count elements ≤ candidate, each count done via binary search in the node’s vector (O(log N)). This yields O(log² N) per query. It is simpler to implement and uses O(N log N) memory, making it attractive when persistence overhead is undesirable or when updates are required.

Examples

Example 1

Input

5 3
1 5 2 6 3
1 5 2
2 4 3
3 3 1

Output

2
6
2

Explanation: Query 1: subarray [1,5] contains {1,5,2,6,3}. Sorted: {1,2,3,5,6}. The 2nd smallest is 2. Query 2: subarray [2,4] contains {5,2,6}. Sorted: {2,5,6}. The 3rd smallest is 6. Query 3: subarray [3,3] contains {2}. The 1st smallest is 2.

Example 2

Input

4 2
10 20 30 40
1 4 4
2 3 1

Output

40
20

Explanation: Query 1: subarray [1,4] is {10,20,30,40}. Sorted: {10,20,30,40}. The 4th smallest is 40. Query 2: subarray [2,3] is {20,30}. Sorted: {20,30}. The 1st smallest is 20.

Example 3

Input

6 3
5 1 4 2 3 6
1 6 3
2 5 2
4 6 5

Output

3
2
-1

Explanation: Query 1: subarray [1,6] is {5,1,4,2,3,6}. Sorted: {1,2,3,4,5,6}. The 3rd smallest is 3. Query 2: subarray [2,5] is {1,4,2,3}. Sorted: {1,2,3,4}. The 2nd smallest is 2. Query 3: subarray [4,6] has only 3 elements, but k=5, so the answer is -1.

Constraints

  • 1 <= N <= 100000
  • 1 <= Q <= 100000
  • 1 <= l <= r <= N
  • -10^9 <= A[i] <= 10^9
  • 1 <= k <= r - l + 1 (if k exceeds subarray length, output -1)

Optimal Approach & Strategy

Build a persistent segment tree (or use parallel binary search with a Fenwick tree) to answer range‑count queries in O(log N); then binary‑search over the value domain to find the k‑th smallest in O(log V·log N) per query.

Brute Force Approach

For each query, extract the subarray A[l..r], sort it, and return the element at index k‑1; if k exceeds the length, return -1.

Verified Code Solutions

JavaScript Solution
Time: O((N + Q) * log N) for persistent tree (building O(N log N) + query O(log N) each) or O((N + Q) * log N * log V) for parallel binary search
function solution(nums) {
   let prefixSum = new Array(nums.length + 1).fill(0);
   for (let i = 0; i < nums.length; i++) {
       prefixSum[i + 1] = prefixSum[i] + nums[i];
   }
   let low = 0, high = nums.length - 1;
   while (low <= high) {
       let mid = Math.floor((low + high) / 2);
       let maxSum = -Infinity;
       for (let i = 0; i <= mid; i++) {
           let sum = prefixSum[i + mid + 1] - prefixSum[i];
           maxSum = Math.max(maxSum, sum);
       }
       if (maxSum == prefixSum[nums.length]) {
           return prefixSum[nums.length];
       } else if (maxSum < prefixSum[nums.length]) {
           low = mid + 1;
       } else {
           high = mid - 1;
       }
   }
   return -1;
}

Asked in Top Tech Interviews

AtlassianMorgan Stanley

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.