Problem Introduction
The goal in this problem is given a set of segments on a line and a set of points on a line, to count, for each point, the number of segments which contain it.
Problem Description
Task.In this problem you are given a set of points on a line and a set of segments on a line. The goal is to compute, for each point, the number of segments that contain this point.
Input Format.The first line contains two non-negative integers \(s\) and \(p\) defining the number of segments and the number of points on a line, respectively. The next \(s\) lines contain two integers \(a_i, b_i\) defining the \(i\)-th segment \([a_i, b_i]\). The next line contains \(p\) integers defining points \(x_1,x_2,\cdots ,x_p\).
Constraints.\(1 \leq s,p \leq 50000;-10^8 \leq a_i \leq b_i \leq 10^8\) for all \(0 \leq i < s;-10^8 \leq x_j \leq 10^8\) for all \(0 \leq j < p\).
Output Format.Output \(p\) non-negative integers \(k_0,k_1,\cdots,k_{p-1}\) where \(k_i\) is the number of segments which contain \(x_i\). More formally,
\(k_i=|{j:a_j \leq x_i \leq b_j}|\)
Sample 1.
Input:
2 3
0 5
7 10
1 6 11
Output:
1 0 0
Sample 2.
Input:
1 3
-10 10
-100 100 0
Output:
0 0 1
Sample 3.
Input:
3 2
0 5
-3 2
7 10
1 6
Output:
2 0
Solution
# Uses python3
import sys
from itertools import chain
def fast_count_segments(starts, ends, points):
cnt = [0] * len(points)
a = zip(starts, [float('-inf')]*len(starts))
b = zip(ends, [float('inf')]*len(ends))
c = zip(points, range(len(points)))
sortedlist = sorted(chain(a,b,c), key=lambda a : (a[0], a[1]))
stack = []
for i, j in sortedlist:
if j == float('-inf'):
stack.append(j)
elif j == float('inf'):
stack.pop()
else:
cnt[j] = len(stack)
return cnt
def naive_count_segments(starts, ends, points):
cnt = [0] * len(points)
for i in range(len(points)):
for j in range(len(starts)):
if starts[j] <= points[i] <= ends[j]:
cnt[i] += 1
return cnt
if __name__ == '__main__':
input = sys.stdin.read()
data = list(map(int, input.split()))
n = data[0]
m = data[1]
starts = data[2:2 * n + 2:2]
ends = data[3:2 * n + 2:2]
points = data[2 * n + 2:]
#use fast_count_segments
cnt = fast_count_segments(starts, ends, points)
for x in cnt:
print(x, end=' ')