Answering Queries Offline with Sweepline
You are given an array and several queries. A query consists of a subarray and
. Print the sum of all elements from this subarray that are .
The current query consists of 2 operations : Sum of elements, and rejecting elements that are greater than
Notice that the queries can be answered offline. This means that you are allowed to precompute the answer to all queries in whichever order you want and only print the answers at the end. Let’s try to answer queries in increasing order of their
Let us start by plotting all the array values (denoted by green dots) and all the
How do we efficiently answer the queries using this diagram? First, let us sort all the queries by their
All green dots that are to the right of the current red dot do not contribute to the answer.
Recall that the green dots represent the array values. Suppose the current red dot is at
Let’s initialise the array as
- At time
, you encounter a green dot. This means that there is some array index that contains the value . So, we recall that index, say , and set . - At time
, you encounter a red dot. This means that there is some query whose value is . So, we recall that index, figure out the corrresponding and and then sum up ALL the values in that range. Why would blindly summing up work? Because we haven’t seen any elements so far. - At time
, 2 new green dots appear. Hence, we locate the corresponding indices and set the value to . - At time
, nothing happens. - At time
, a red dot appears. We can find out the corresponding and and print the subarray sum. - At time
, a green dot appears. We locate the corresponding index and set its value to . - At time
, 2 red dot appears. This means that we need to answer 2 queries (with possibly different and ) but with same . Just like before, we can get the entire subarray sum and print the answer.
If we iterate the queries as well as the array elements in increasing order (simultaneously), the operation simplifies to sum of a subarray and updating a particular index. This technique is known as Sweep Line. You plot entities with different colours and start traversing the number line from left to right, one step at a time. Every time you take a step, you encounter some entities for each color. These are known as events. Then, you decide on what to do with those entities, precompute the answer to some queries and then move on to the next step. The dotted lines are the ones sweeping the plane from left to right and witnessing certain events at each timestamp.
Note that the time complexity of the naive implementation would be
a = [0 .... 0]
for t in range(1, 10^9):
# Locate all green dots and add them to the array
for all i such that original_array[i] = t:
a[i] = t
# Locate the red dots and answer the query
for all q such that query[q].x = t:
ans[q] = sum(a[query[q].L ... query[q].R])
print(ans)
Now, let us talk about some optimizations that we could do to improve the time complexity. First, let us remove the outer loop that iterates over each timestamp from
Let’s sort the array elements (along with record for their original indices) as well as query elements (on the basis of
for i in range(n):
sorted_a.append({a[i], i})
sort(sorted_a)
last_index = 0
for t in sorted(queries.x):
# Locate all green dots that appeared after the last sweep
while(last_index < n and sorted_a[last_index].value <= t):
a[sorted_a[last_index].i] = sorted_a[last_index].value
# Locate all red dots on this line and answer them
# Find index q such that query[q] = t and answer it.
ans[q] = sum(a[query[q].L ... query[q].R])
print(ans)
The time complexity is now
You can find the code here
You are given a tree and some queries. In each query
print YES if there is a path from to such that the maximum value on that path is .
This is a fairly standard follow up problem to sweep line. I will add my solution and explanation after a couple of AC submissions on the practice contest. If you need any hints for this problem, or if you are unable to use Atcoder’s segment tree library on Codeforces, you can ask on my discord server or twitter