Кол-во вершин на расстоянии не более k в дереве

Правка ru11, от rafaeLL, 2026-09-07 20:02:49

Задача 1

Дано корневое дерево и число $$$k$$$. Для каждой вершины $$$u$$$ найти кол-во вершин в поддереве вершины $$$u$$$ отдаленных от $$$u$$$ на расстояние не более $$$k$$$ рёбер.

Рассмотрим решение за $$$O(N)$$$. При этом возникнет забавная структура — RQ на stack-е с запросами $$$O(1)$$$ (по сути префикс-сумма). $$$ $$$

Решение

Запускаем DFS. При обходе будем хранить стек чисел: вершине пути на глубине $$$h$$$ соответствует $$$h$$$-ый индекс стека.

  • При входе в новую вершину, увеличиваем значения в интервале стека $$$[h-k, h)$$$ на единицу. И push-ем $$$1$$$ в стек.

  • При выходе из вершины, сохраняем последнее значения стека в вершину соответствующего поддерева (это если что подсчитан ответ: кол-во вершин на расстояние не более $$$k$$$). И затем делам pop в стеке.

Оказывается эти операции с стеком можно выполнять за $$$O(1)$$$:

  • Для увеличения на интервале выполняем: diff[l] -= delta; diff[r] += delta;

  • При pop() выполняем "пропихивание": diff[l-1] += diff[l];

Код

Можно слегка модифицировать (аккумулировать сколько к текущему моменту вершин ниже этой высоты) и решать: Дано корневое дерево. Надо оффлайн отвечать на запросы: $$$(u,k)$$$ — количество вершин поддерева $$$u$$$, отдаленных от $$$u$$$ на расстоянии не более чем $$$k$$$ рёбер ($$$k$$$ для каждого запроса своё).

После поисков нашёл задачу где используется что-то схожее — хранение пути от корня в DFS: F. Два поддерева (решение).


Если рассматривать не только вершины в поддереве, а все вершины в дереве, то такую задачу можно решить за $$$O(N \ln N)$$$:

Задача 2

Дано дерево и число $$$k$$$. Для каждой вершины $$$u$$$ найти кол-во вершин во всем дереве отдаленных от $$$u$$$ на расстояние не более $$$k$$$ рёбер. (источник) (похожая задача)

Вообще Задача 1 возникла в попытке решить Задачу 2 за $$$O(N)$$$, но у меня ничего не вышло и только получалось что-то похожее на переливайку (внезапно зашарилось). (Хотелось бы воспользоваться rerootin-ом, однако тогда для корня надо знать результаты для дистанций { $$$k, k-1$$$ }, чтобы подсчитать результат для дистанции { $$$k$$$ } у ребёнка. В итоге у ребёнка теряется результат для дистанции { $$$k-1$$$ }, и как его можно оптимально восстанавливать не понятно.)

соре за бред, писалось 15 месяцев назад, для увеличения шума в интернете оставлю этот блог (+ постарался уменьшить ерунды)

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
ru11 Русский rafaeLL 2026-09-07 20:02:49 2708 сделал более читаемым
ru10 Русский rafaeLL 2025-05-29 23:38:34 12
ru9 Русский rafaeLL 2025-05-29 20:48:20 17
ru8 Русский rafaeLL 2025-05-29 20:45:07 2 Мелкая правка: ' мало попадалось стат' -> ' мало попалось стат'
ru7 Русский rafaeLL 2025-05-29 20:44:07 9
ru6 Русский rafaeLL 2025-05-29 20:41:06 0 (опубликовано)
ru5 Русский rafaeLL 2025-05-29 20:37:54 239 Мелкая правка: '$\n\n---\n#### Реш' -> '$\n\n---\n\n#### Реш'
ru4 Русский rafaeLL 2025-05-29 20:24:37 657
ru3 Русский rafaeLL 2025-05-29 20:06:26 593 Мелкая правка: 'n[cut]\n\n $ $\n\nПочему' -> 'n[cut]\n\n---\n\nПочему'
ru2 Русский rafaeLL 2025-05-29 19:34:35 2005 Мелкая правка: '**Задача 1.**\n> Дано корне' -> '##Задача 1.\nДано корне'
ru1 Русский rafaeLL 2025-05-29 19:22:28 1208 Первая редакция (сохранено в черновиках)