-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bc3f1f0
commit 35642a8
Showing
6 changed files
with
87 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import bisect | ||
|
||
|
||
# O((n + m)log(n + m)) | ||
def count_segments(segments: list[tuple[int, int]], points: list[int]) -> list[int]: | ||
m = len(points) | ||
# Формируем список событий | ||
events: list[tuple[int, int, int]] = [] | ||
for x0, x1 in segments: | ||
# Начало отрезка - вклад в ответ +1 | ||
events.append((x0, 1, 0)) | ||
# Конец отрезка - вклад в ответ -1 | ||
events.append((x1, -1, 0)) | ||
for i, x in enumerate(points): | ||
# Появление точки - вклад в ответ 0, записываем индекс (он нужен для сохранения порядка в result) | ||
events.append((x, 0, i)) | ||
# Сортируем события: по возрастанию X координаты, по убыванию вклада в ответ | ||
events.sort(key=lambda entry: (entry[0], -entry[1])) | ||
# Считаем ответ. result[i] - ответ для i-й точки | ||
result = [0] * m | ||
# Текущий ответ (сколько отрезков пересекает точка) | ||
count = 0 | ||
for _, contribute, i in events: | ||
# Если это отрезок, меняем ответ в соответствии с вкладом в него | ||
if contribute != 0: | ||
count += contribute | ||
# Если это точка, то записываем её ответ | ||
else: | ||
result[i] = count | ||
return result | ||
|
||
|
||
# O(n log n + m log n) = O((n + m) log n) | ||
def count_segments_bisect(segments: list[tuple[int, int]], points: list[int]) -> list[int]: | ||
# Формируем список начал и концов отрезка | ||
x0_all, x1_all = [], [] | ||
for x0, x1 in segments: | ||
x0_all.append(x0) | ||
x1_all.append(x1) | ||
# Сортируем события | ||
x0_all.sort() | ||
x1_all.sort() | ||
# Вычисляем ответ | ||
result = [] | ||
for x in points: | ||
# Сколько отрезков начинаются в точке x или левее | ||
high = bisect.bisect_right(x0_all, x) | ||
# Сколько отрезков заканчиваются строго левее точки x | ||
low = bisect.bisect_left(x1_all, x) | ||
# Количество отрезков, пересекающих точку | ||
count = high - low | ||
# Добавляем ответ | ||
result.append(count) | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
# O(n log n) | ||
def min_set_of_points(segments: list[tuple[int, int]]) -> list[int]: | ||
n = len(segments) | ||
# Сортируем отрезки по правому концу. | ||
segments.sort(key=lambda x: x[1]) | ||
cover = [] | ||
# Сортируем отрезки по правой границе | ||
segments.sort(key=lambda entry: entry[1]) | ||
i = 0 | ||
# Покрытие точками | ||
cover = [] | ||
# Пока не покроем все отрезки | ||
while i < n: | ||
segment = segments[i] | ||
cover.append(segment[1]) | ||
# Пропускаем пересекающиеся отрезки. | ||
while i < n and segments[i][0] <= segment[1]: | ||
# Добавляем минимальный конец отрезка в покрытие | ||
x = segments[i][1] | ||
cover.append(x) | ||
# Пропускаем отрезки, покрытые точкой x | ||
while i < n and segments[i][0] <= x: | ||
i += 1 | ||
return cover |
This file was deleted.
Oops, something went wrong.