Скелеты, кости, кладбище, черепа

Автор задачи и разработчик: Павел Скобелин

Давайте поймем, что происходит при разрезании графа одной вертикальной чертой $$$x = C$$$. Он разбивается на два графа: все вершины с $$$x_i < C$$$, и все вершины с $$$x_i > C$$$. Тогда количество компонент связности в получившемся графе будет равно сумме количества компонент связности в левом и правом графе.

Предподсчитаем количество компонент связности в графе с вершинами левее $$$C$$$ для каждого $$$C$$$. Для этого отсортируем вершины по $$$x$$$-координате и будем добавлять их в граф по очереди, поддерживая количество компонент связности с помощью системы непересекающихся множеств. Таким образом, для каждого $$$C$$$ мы получим, сколько компонент связности в графе, все вершины которого левее $$$C$$$.

Сделаем аналогичный проход справа налево и получим ответ для правой части. Теперь, для ответа на запрос нужно воспользоваться бинарным поиском, чтобы найти запомненные для данного $$$C$$$ значения, и сложить количество компонент связности в левой и правой части графа. Если изначально сделать сжатие координат, то можно обойтись и без бинпоиска.

Таким образом, сортировка работает за $$$\mathcal{O}(n \log n)$$$, предподсчет за $$$\mathcal{O} (n \cdot \alpha (n))$$$, и ответ на запрос за $$$\mathcal{O}(\log n)$$$.