CSES - Restaurant Customers
Authors: Michael Cao, Neo Wang
Appears In
In this problem, we're given 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 , where is the number of intervals that cover each point . We can do this by looping through each interval and increasing by for each index in .
This results in a time complexity (where ), which easily times out (think what happens when the interval is queried times).
We can do better. It's easy to see that an increment of (before computation) in causes all subsequent (after computation) to increase by . We can also "undo" this operation by adding to . 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 because the interval is inclusive - decrementing at point turns the interval to .
Example 1: Add two to each point in the interval
Our array after adding 2 at our increment (start) point (before computation)
0 | 0 | 2 | 0 | 0 | 0 |
Our prefix sum after adding 2 at our increment (start) point (and computing).
0 | 0 | 2 | 2 | 2 | 2 |
Our prefix sum after subtracting 2 at our decrement point (and computing).
0 | 0 | 2 | 2 | 2 | 0 |
Observe that this works for multiple intervals.
Example 2: Add two to each point in and one to each point in
Adding interval with increment point at and decrement at
0 | 0 | 2 | 0 | 0 | -2 |
Adding interval with increment point at and decrement at
0 | 1 | 2 | 0 | -1 | -2 |
After computation
0 | 1 | 3 | 3 | 2 | 0 |
In this problem, our is fixed at . As a result, when we encounter a starting point, we can increment by , and for an endpoint, decrement by . We actually cannot compute the prefix sum array directly since , and we will run out of memory when creating an array of size .
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!