Общая идея этого алгоритма заключается в сортировке точек и затем проходу по ним(по этому алгоритм так и называется).
Давайте разберем несколько задач на эту тему и лучше поймем алгоритм.
Пусть, дан набор из
Понятно, что каждую точку прямой мы проверить не можем. В каких точках прямой может происходить смена количества отрезков, которыми она покрыта? Только в началах или концах данных отрезков. Назовем такие точки интересными. Так как смена ответа может происходить только в интересной точке, максимум достигается так же в какой-то из интересных точек. Отсюда сразу следует решение за
Это решение можно улучшить. Отсортируем интересные точки по возрастанию координаты. Пройдем по интересным точкам слева направо, поддерживая количество отрезков
Заметим, что если координаты двух интересных точек совпали, чтобы получить правильный ответ, сначала надо рассмотреть начала отрезков, а потом концы.
Как такое писать: нужно представить интересные точки в виде структур с полями “координата” и “тип” (начало/конец) и отсортировать со своим компаратором. Удобно начало отрезка обозначать +1, а конец -1, чтобы прибавлять к
struct event{
int x, type;
};
int main(){
int n;
cin >> n;
vector<event> a(n);
for (int i = 0; i < n; ++i)
cin >> a[i].x >> a[i].type;
sort(a.begin(), a.end(), [](const event& e1, const event& e2) {
return e1.x == e2.x ? e1.type < e2.type : e1.x < e2.x;
});
}
Такое решение работает за
Пусть, теперь надо для
Воспользуемся следующим приемом: сразу считаем все запросы и сохраним их, чтобы потом ответить на все сразу. Добавим точки запросов в массив интересных точек с новым типом 0, который будет означать, что в этой точке надо ответить на запрос. В случае равенства координат запросы должны идти после начал и до концов. Точно так же отсортируем точки и пройдем по точкам слева направо, поддерживая
Пусть, дан набор из
Вместо того, чтобы считать количество отрезков, с которыми отрезок пересекается, посчитаем количество отрезков, с которыми он не пересекается, и вычтем это число из
Будем считать, что изначально ответ для всех отрезков равен
Заметим, что теперь в структуре точки необходимо хранить еще и номер отрезка, которому она принадлежала. Время работы
Пусть, дан набор из
Как обычно, отсортируем интересные точки и при проходе поддерживаем число отрезков, покрывающих данную точку. Если оно больше 0, то отрезок который мы прошли с прошлой рассмторенной точки принадлежит объединению. Время работы
Это общая идея, которая может оказаться полезной. Пусть, есть
int a[n], all[n];
for (int i = 0; i < n; ++i) {
cin >> a[i];
all[i] = a[i];
}
sort(all, all + n);
m = unique(all, all + n) - all; // теперь m - число различных координат
for (int i = 0; i < n; ++i)
a[i] = lower_bound(all, all + m, x[i]) - all;
Решите как можно больше задач из контеста https://informatics.msk.ru/mod/statements/view.php?id=33318