CSES - Restaurant Customers

Authors: Michael Cao, Neo Wang

In this problem, we're given nn intervals with distinct start and end points, and we want to find the maximum number of intervals overlapping some point.

Solution

We can use prefix sums to determine the number of intervals that cover any particular point, and then find the maximum number in the sum.

A naïve approach is to create an array ctr\texttt{ctr}, where ctr[i]\texttt{ctr}[i] is the number of intervals that cover each point ii. We can do this by looping through each interval [a,b][a,b] and increasing ctr[i]\texttt{ctr}[i] by 11 for each index in aiba \leq i \leq b.

This results in a O(nV)\mathcal{O}(nV) time complexity (where 0abV0 \leq a \leq b \leq V), which easily times out (think what happens when the interval [0,V][0, V] is queried nn times).

We can do better. It's easy to see that an increment of xx (before computation) in arr[i]\texttt{arr}[i] causes all subsequent prefix[i...V]\texttt{prefix}[i...V] (after computation) to increase by xx. We can also "undo" this operation by adding x-x to arr[i]\texttt{arr}[i]. This concept can be conceptualized through increment and decrement points. An increment point increases (and decrement decreases) all subsequent cells. Note that our decrement point is located at B+1B+1 because the interval is inclusive - decrementing at point BB turns the interval to [A,B)[A, B).

Example 1: Add two to each point in the interval [2,4][2, 4]

Our array after adding 2 at our increment (start) point (before computation)

002000

Our prefix sum after adding 2 at our increment (start) point (and computing).

002222

Our prefix sum after subtracting 2 at our decrement point (and computing).

002220

Observe that this works for multiple intervals.

Example 2: Add two to each point in [2,4][2, 4] and one to each point in [1,3][1, 3]

Adding interval [2,4][2, 4] with increment point at 22 and decrement at 4+1=54+1=5

00200-2

Adding interval [1,3][1, 3] with increment point at 11 and decrement at 3+1=43+1=4

0120-1-2

After computation

013320

In this problem, our xx is fixed at 11. As a result, when we encounter a starting point, we can increment by 11, and for an endpoint, decrement by 11. We actually cannot compute the prefix sum array directly since V109V \leq 10^9, and we will run out of memory when creating an array of size VV.

Instead, we can either coordinate compress and compute the prefix sum over interesting intervals or sweep over the intervals while maintaining a running prefix sum.

Implementation 1

If we put the start and end points into a list and sort them, all we need to do is find the max sum of values over all prefixes of the list.

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()

Implementation 2

Coordinate compress interval endpoints and only compute the prefix sum array for interesting intervals.

C++

#include <bits/stdc++.h>
using namespace std;
#define vt vector
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORE(i, a, b) for(int i = (a); i <= (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); i++)
#define trav(a, x) for (auto& a : x)

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!