Персистентное декартово дерево по неявному ключу

Округлые формы для интересного ландшафтного дизайна

Кустарников и деревьев, у которых от природы шарообразная крона в природе очень мало, а для средней полосы их список и вовсе совсем короткий. Речь идет не о тех растениях, которые можно остричь секатором и придать им форму шара, а о деревьях и кустах, у которых крона по природе в виде идеального шара.

Ни один ландшафтный дизайнер не обойдет стороной это чудо природы, дело в том, что округлые формы заметно расширяют пространство вокруг себя, а на маленьких участках такой визуальный обман творит чудеса. 

Как влияет форма и фактура на зрительные образы?

Светлые по цвету шары и круги значительно расширяют пространство вокруг себя, особенно часто такой визуальный обман используют дизайнеры в узких проходах и на маленьких площадях, когда нужно зрительно «вытянуть» ту или иную часть пространства. Еще один вариант «игры с пространством» — посадка темных и светлых шаровидных растений, такой эффект поможет сделать переходы мягче.

Правильными шарами любых размеров можно разнообразить пейзажную композицию, сделать ее более хаотичной. Особенно хорошо это работает, когда шары контрастируют с основным наполнением композиции цветом и фактурой.

Шаровидные растения вписываются в любой стиль, благодаря чему являются фаворитами у ландшафтных дизайнеров.

Еще один интересный вариант  — это использование округлой формы кроны деревьев как зонтика для создания тени вблизи скамеек для отдыха или детских площадок.

Искусственные и природные шары

Самый простой вариант – это выбрать для посадки дерево либо куст с родной шаровидной формой, который не будет нуждаться в дополнительной стрижке. Но если задача стоит — придать форму шара растениям, которые ранее были высажены на территории, то без стрижки не обойтись.

Для этих целей конечно лучше всего привлекать профессионала, так как придать форму идеального круга, без определенных навыков, весьма сложно.

Виды шаровидных растений

Все шаровидные растения можно условно разделить на два вида: вечнозеленые и листопадные. К первым относятся растения, чья листва сохраняется в течение всего года, ко вторым — деревья и кустарники, листва которых опадает в определённое время года.

Вечнозеленые растения округлой формы

Выбор вечнозеленых шаровидных растений довольно большой: ели, сосны, можжевельники и туи. Но далеко не у всех представителей этих видов кроны в форме шара, здесь нужно ориентироваться в тех или иных сортах. В большинстве своем хвойные деревья и кустарники — растения светолюбивые. Это означает, что для здорового роста и развития им нужно достаточно света, простор и подходящее место посадки.

Если говорить о закаленности, то большинство хвойных растений устойчивы к холоду.

Туя западная

Сосна горная

Ель обыкновенная

Ель канадская или сизая

Можжевельник китайский

Листопадные деревья с округлой кроной

Самые популярные представители листопадных шаровидных растений – клен, боярышник, каштан и ива. В отличии от хвойных, они более привередливы к температуре, более того, встречаются весьма рослые представители этих деревьев, так что лучше при покупке уточнить возможные габариты растения и найти подходящее место для него.

Клен остролистный

Боярышник однопестичный

Конский каштан обыкновенный

Ива ломкая. опубликовано econet.ru

Применение сортировки

Пары последовательных значений последовательности (показано в виде толстых красных ребер) , что в кронштейн значение последовательности х (темнее синяя точку). Стоимость включая й в отсортированном порядке , полученном с помощью алгоритма Levcopoulos-Петерсон пропорциональна логарифму этого числа Брекетинга пара.

описывает алгоритм сортировки на основе декартовых дерев. Они описывают алгоритм, основанный на дереве с максимумом на корню, но она может быть изменена прямолинейно для поддержки декартово дерево с конвенцией , что минимальное значение находится в корневом каталоге. Для согласованности, то это модифицированная версия алгоритма, описанного ниже.

Алгоритм Levcopoulos-Петерсона можно рассматривать как вариант выбора вида или кучи сортировки , который поддерживает приоритет очереди кандидата в минимумов, и что на каждом шаге находит и удаляет минимальное значение в этой очереди, перемещая это значение до конца вывода последовательность. В своем алгоритме очередь приоритет состоит только из элементов, родитель в декартовой дереве уже были найдены и удалены. Таким образом, алгоритм состоит из следующих этапов:

  1. Построить декартово дерево для входной последовательности
  2. Инициализировать очереди приоритета, первоначально содержащие только корень дерева
  3. В то время как очереди приоритетов не является пустым:
    • Найти и удалить минимальное значение х в приоритетной очереди
    • Добавить й в выходной последовательность
    • Добавить декартовы дерево детей х в приоритетной очереди

Как Levcopoulos и Петерсона шоу, для входных последовательностей, которые уже почти отсортированных, размер очереди приоритета будет оставаться небольшим, что позволяет этот метод , чтобы воспользоваться почти отсортированных входных данных и работать более быстро. В частности, время , в худшем случае запуска этого алгоритма O ( п  войти  K ), где K представляет собой среднее, по всем значениям х в последовательности, из числа последовательных пар последовательности значений , которые кронштейн х . Они также доказать нижнюю границу о том , что для любых п и К  = со (1), любой алгоритм сортировки на основе сравнения должны использовать Ω ( п  войти  K ) сравнения для некоторых входов.

Приоритеты и асимптотика

В декартовом дереве логарифмическая высота дерева гарантируется не инвариантами и эвристиками, а законами теории вероятностей: оказывается, что если все приоритеты (\(y\)) выбирать случайно, то средняя глубина вершины будет логарифмической. Поэтому ДД ещё называют рандомизированным деревом поиска.

Теорема. Ожидание глубины вершины в декартовом дереве равно \(O(n \log n)\).

Доказательство. Введем функцию \(a(x, y)\) равную единице, если \(x\) является предком \(y\), и нулем в противном случае. Такие функции называются индикаторами.

Глубина вершины равна количеству её предков — прим. К. О. Таким образом, она равна

\

Её матожидание равно

\ = E = \sum_{j \neq i} E = \sum_{j \neq i} E = \sum_{j \neq i} p(j, i)
\]

где \(p(x, y)\) это вероятность, что \(a(x, y) = 1\). Здесь мы воспользовались важным свойством : матожидание суммы чего угодно равна сумме матожиданий этого чего угодно.

Теперь осталось посчитать эти вероятности и сложить. Но сначала нам понадобится вспомогательное утверждение.

Лемма. Вершина \(x\) является предком \(y\), если у неё приоритет больше, чем у всех вершин из полуинтервала \((x, y]\) (без ограничения общности, будем считать, что \(x ).

Необходимость. Если это не так, то где-то между \(x\) и \(y\) есть вершина с большим приоритетом, чем \(x\). Она не может быть потомком \(x\), а значит \(x\) и \(y\) будут разделены.

Достаточность. Если справа будет какая-то вершина с большим приоритетом, то её левым сыном будет какая-то вершина, которая будет являться предком \(x\). Таким образом, всё, что справа от \(y\), ни на что влиять не будет.

У всех вершин на любом отрезке одинаковая вероятность иметь наибольший приоритет. Объединяя этот факт с результатом леммы, мы можем получить выражение для искомых вероятностей:

\

Теперь, чтобы найти матожидание, эти вероятности надо просуммировать:

\ = \sum_{j \neq i} p(j, i) = \sum_{j \neq i} \frac{1}{|i-j|+1} \leq \sum_{i=1}^n \frac{1}{n} = O(\log n)
\]

Перед последним переходом мы получили сумму гармонического ряда.

Примечательно, что ожидаемая глубина вершин зависит от их позиции: вершина из середины должна быть примерно в два раза глубже, чем крайняя.

Упражнение. Выведите из этого доказательства асимптотику .

Сгибание и наклон ветвей и побегов

Усиление закладки плодовой древесины на наклоненных и согнутых ветвях считали результатом лучшего обогащения их питательными веществами, отток которых, как предполагали, задерживался.

Исследования, проведенные Л. Б. Штернбергом и Р. О. Куликовой (1957), не подтвердили этого предположения. Оказалось, что наклон ветвей вызывает изменения в распределении органических и ростовых веществ вдоль побега. Углеводы по побегу распределяются при его наклоне более равномерно, а количество азота уменьшается к верхушке.

Несколько иначе распределяются питательные вещества при сгибании ветви. Найдено, что больше всего их накапливается в верхушке побега, направленной вниз, а не в месте сгиба (Храмов, Булычев; 1967, 1970). Для стимулирования   закладки    цветковых   почек   молодые побеги изгибают и наклоняют в фазу замедленного роста (в конце лета), когда дерево не может возобновить активный рост и образовать на сгибе волчковые побеги, но в точках роста еще идет усиленное деление меристемы. Двулетние и многолетние ветви наклоняют весной.

Для сгибания и наклона ветвей используют различные крепления (пружинки, бельевые прищепки, зажимы) или подвязывают их к кольям, стволу и другим ветвям. Перевод в наклонное положение ускоряет старение ветвей, поэтому не исключена необходимость применения обрезки.

Что это декоративное садоводство

Декоративное (формовое) садоводство — это выращивание плодовых деревьев на различных подвоях, с искусственно сформированной кроной. Обычно так выращивают яблони и груши, так как эти деревья очень пластичны и хорошо переносят обрезку. Формировать крону можно и у косточковых деревьев, а также плодовых и декоративных кустарников.

Персистентное декартово дерево по неявному ключуПерсистентное декартово дерево по неявному ключу

На садовом участке плодовые деревья с необычной формой кроны не только будут служить украшением, и придавать саду оригинальный вид, но и приносить хороший урожай — у них более крупные плоды.

За растениями удобно ухаживать и снимать с них плоды, они требуют меньше места.

Сажать деревья нужно с южной, юго-западной или юго-восточной стороны. При такой посадке деревья защищены от холодных северных ветров зимой и, следовательно, меньше страдают от морозов

Кроме того, возле стены создается благоприятный для растений микроклимат, что также немаловажно: тепло аккумулируется в этом месте, и это дает возможность выращивать более теплолюбивые растения, а также получать лучший урожай

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

Плоские кроны

У деревьев с плоскими искусственными кронами скелетные ветви размещают в ряду в одной вертикальной плоскости. В междурядья их не направляют. При таком размещении ветвей создается наилучший воздушно-световой режим.При пальметтном формировании кроны наиболее гармонично складывается соотношение между проводящими и обрастающими частями дерева. Из плоских крон наибольшее распространение в практике получили косая пальметта и плоский шпиндельбуш (разновидность веретеновидной кроны):

Косая пальметта

Условиям интенсификации садоводства наиболее полно отвечают деревья с кронами в виде косой пальметты. Такая система формирования позволяет увеличить количество деревьев на 1 га до 506—600. Плоская крона толщиной 2—2,5 м обеспечивает высокую продуктивность плодовых образований. С биологической точки зрения у пальметтной кроны экономно построены проводящие и скелетные части. Пальметтная форма кроны позволяет выращивать плоды высоких товарных достоинств. Применение ее является новым этапом в развитии садоводства. При высоком уровне агротехники пальметтные сады ежегодно дают 400—500 ц плодов с 1 га.

Пальметтную крону с наклоненными ветвями создают из 6 скелетных ветвей, размещенных в трех ярусах.

Ветви Н порядка в зависимости от сорта закладывают с промежутками 15—20 см по бокам каждой скелетной ветви. Длина ветвей II порядка в нижнем ярусе достигает 100—150 см.Чем ближе к верхушке скелетного сука располагается ветвь II порядка, тем меньше ее длина. На верхушках ветвей второго и третьего ярусов их превращают в мелкие плодовые разветвления. При таком формировании яблони в пальметтном саду размещают в ряду на расстоянии 3,5—4 м друг от друга и между рядами—. 5 м.

При формировании деревьев в форме пальметты необходимо учитывать биологические особенности сортов. По мнению П. А. Храмова % А. П. Булычева (1970), для создания устойчивой и урожайной пальметты наиболее удобны сорта с пирамидальной кроной. Сорт Антоновка в пальметтной форме мало изучен. У сорта Боровинка, отличающегося хрупкой древесиной,, для укрепления скелета дерева ветви оставляют несколько приподнятыми (угол отклонения 45—50°). Для построения первого,яруса у сорта Мелба отбирают нижние ветви, но вначале придают им более вертикальное положение, так как проводник склонен к значительному преобладанию в росте. У сорта Пепин шафранный нижние ветви не всегда пригодны для закладки первого яруса, Г. А. Березовский (1967) относит этот сорт к особенно перспективным, как обладающий большой восстановительной способностью.

Не у всех сортов наклон веток усиливает закладку почек (Романов, 1972). Для пальметтных садов лучше брать сорта с ежегодным плодоношением.

В настоящее время в результате поисков более простого способа формирования пальметты возникло несколько вариантов пальметтных крон. А. И. Ильинским (1972), например, предложена пальметта, названная им харьковской, при формировании которой подвязка веток и побегов заменяется обрезкой. Подвязывают (к проволоке) только ветви I порядка. При таком способе формирования урожай не уменьшается, плоды сохраняют высокие товарные качества, а затраты труда значительно сокращаются.

Плоский шпиндельбуш

Ветви деревьев, сформированные по этой форме отклонены в горизонтальном направлении. Все ветви, отходящие от центрального ствола, размещают в одной плоскости вдоль ряда.При формировании плоского шпиндельбуша поддерживают рост центрального проводника, ежегодно укорачивая однолетний прирост его до длины 25—30 см. Боковые разветвления отгибают в горизонтальном направлении в конце периода роста побегов или весной следующего года.

При зимней обрезке удаляют на кольцо все вертикальные сильные побеги, образовавшиеся на верхней стороне ветвей I порядка. У взрослых деревьев прореживают плодовые ветки, а также полускелетные ветви, которые оставляют на расстоянии 12—15 см друг от друга. Ширина плодовой стены при формировании деревьев в форме плоского шпиндельбуша не превышает 1,5—2 м.В садах Северо-Западной зоны пока не распространены деревья с плоскими кронами. Формирование таких крон в производственной практике оспаривается в связи с трудоемкостью этой работы.

Деревья с плоской кроной и фото декоративного сада своими руками

Искусственно сформированная крона у деревьев может быть плоской — когда ветви расположены в одной плоскости — или объемной. В этом случае ветви расположены так, что образуют нужную форму. Пальметта, одноплечий и двуплечий кордоны являются примерами плоской кроны.

Перед тем как впервые сделать декоративный сад, освойте принцип  формирования кроны типа пальметта — свободный или симметричный. Используйте для этого однолетний или двулетний саженец яблони, привитый на дичок или, в более южных районах, на карликовый подвой. В любом случае нужно использовать хорошие, районированные сорта яблони или груши.

Персистентное декартово дерево по неявному ключуПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключуПерсистентное декартово дерево по неявному ключу

Посмотрите выше на фото декоративного сада, созданного своими руками вблизи какой-либо постройки: он смотрится очень красиво, дает неплохой урожай и занимает немного места.Таким пристенным садом можно декорировать стены садового домика или хозяйственных построек.

Деревья сажают и вдоль изгороди или садовых дорожек. Кроны у них располагаются в одной плоскости, можно сделать пальметту веерную или симметричную. У свободной, или веерной, пальметты расстояния между ветками произвольные, такая крона дерева наиболее приближена к естественной. У симметричной пальметты расстояния между ветками одинаковые. Сначала нужно изготовить каркас из деревянных планок и проволоки. Расстояние между планками должно составлять около 30 см. Вдоль каркаса нужно выкопать посадочную траншею (если деревьев будет несколько) или яму (для одного дерева). Расстояние между деревьями и стеной дома должно быть не менее 1 м.

Персистентное декартово дерево по неявному ключу

Кроны деревьев формируют в одной плоскости — по мере роста их ветви, расположенные в нужной плоскости, подвязывают к каркасу, а остальные — вырезают. В загущенных местах лишние ветви удаляют, а для того чтобы выровнять в росте сильнорастущие и слаборастущие ветви, производят обрезку на неодинаковую длину. Сильнорастущие ветви подвергают значительной обрезке, а слаборастущие подрезают на небольшую длину либо вообще не трогают.

Помните: высота штамба должна в любом случае составлять 50-60 см.

Для того чтобы получить перегиб ветвей, их сначала подвязывают под углом 30-40°. Это делается для того, чтобы ветви не отставали в росте. Когда они окрепнут, их пригибают сильнее и подвязывают к каркасу, располагая в нужном направлении. Обрезку выполняют 2 раза за сезон.

Центральный проводник при каждой обрезке укорачивают. Те ветви, которые нарушают форму, удаляют. Оставшиеся ветви не затеняют друг друга, хорошо освещены и проветриваются, поэтому урожаи на таких деревьях не ниже, а зачастую даже выше урожаев с обычных деревьев. Такой пристенный сад выглядит оригинально и занимает гораздо меньше места, чем обычный.

Выбор плакучего дерева

Как и обычные деревья с нормальной формой кроны, плакучие деревья имеют большое разнообразие видов и сортов. Их можно подобрать к любой планировке и стилю ландшафтного дизайна. Так как некоторые деревья любят расти в тени, другие на влажной почве, некоторые очень красивы в период цветение, а некоторые полностью преобразуются и достигают пика своей красоты осенью.

Плакучая ива – плакучая форма дерева, созданная природой. Представляет собой не очень высокое дерево, не вше 15 метров, с длинными, очень гибкими ветвями. Цветение происходит очень длинными красивыми сережками. Такое дерево не прихотливо почвам, но лучше всего растет на суглинках. Сразу после посадки требует обильного полива. Плохо переносит холодное время года, поэтому деревце желательно укрывать на зиму. Из деревцев плакучей ивы получаются красивые аллеи, перголы и живые изгороди.

Персистентное декартово дерево по неявному ключуПлакучая ива ы саду на дачеПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Плакучая береза, ее еще принято называть бородавчатой или повислой, высокое, стройное дерево, которое может достигать в высоту более 20 метров. Деревце хорошо переносит морозы и отличается быстрыми темпами роста. Любит открытые солнечные места, к почвам неприхотлива.

Персистентное декартово дерево по неявному ключуПлакучая береза в саду на дачеПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Ясень плакучий представляет собой невысокое дерево. Ясень редко превышает 8 метров в высоту. Предпочитает почвы с высоким содержанием кальция, любит светлые участки. Наиболее выгодно плакучий ясень смотрится в одиночных посадках.

Персистентное декартово дерево по неявному ключуЯсень плакучий в саду на дачеПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Акация плакучая – очень выносливое деревце, достигающее в высоту не более двух 2 метров. Тенеустойчивое, переносит как сильные засухи, так и морозы, может расти на любых почвах. Весной цветет красивыми соцветиями желтого цвета, в летний период листва дерева приобретает насыщенно-зеленый цвет.

Персистентное декартово дерево по неявному ключуАкация плакучая в саду на дачеПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Все чаще садоводы на своих участках высаживают различные хвойные растения с плакучей формой кроны.

Плакучая сосна. Наиболее популярны три вида плакучей сосны: веймутова, черная и желтая. Все эти виды сосны светолюбивы, отлично переносят морозы и засухи, могут расти на любой почве. Отличатся густой ниспадающей кроной, которая не потеряет своей красоты даже в зимний период времени.

Персистентное декартово дерево по неявному ключуСосна плакучая в соду на дачеПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Лиственница плакучая – растение достигает в высоту 6-10 метров, ширина кроны может достигать трех метров. Лучше всего растет на хорошо дренируемых, плодородных почвах, хотя отлично приспособится и к другим условиям проживания. Лиственница – светолюбивое растение, имеет иголки светло-зеленого цвета, которые к зиме приобретают желтую окраску. Наиболее выгодно эти растения смотрятся в групповых посадках.

Персистентное декартово дерево по неявному ключуЛиственница плакучая в саду на дачеПерсистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Персистентное декартово дерево по неявному ключу

Treaps

Так как декартово дерево представляет собой бинарное дерево, то естественно использовать его в качестве бинарного дерева поиска для упорядоченной последовательности значений. Однако, определение декартова дерева , основываясь на один и те же значения , которые образуют поисковые ключи двоичного дерева поиска не работают: декартово дерево отсортированной последовательности просто путь , коренится в его крайней левой конечной точке, и двоичный поиск в этом дереве вырождается последовательного поиска в пути. Тем не менее, можно сформировать более сбалансированные деревья поиска путем генерирования приоритетных значений для каждого ключа поиска, которые отличаются от самого ключа, сортировка входов их ключевых значений, а также с помощью соответствующей последовательности приоритетов , чтобы сгенерировать декартово дерево. Эта конструкция может быть эквивалентно рассматривать в рамках геометрических описанных выше, в которой х -координатах из множества точек являются ключами поиска , и у -координаты являются приоритетными.

Эта идея была использована , который предложил использовать случайные числа в качестве приоритетов. Структура данных в результате этого случайного выбора называется декартово дерево , благодаря сочетанию бинарного дерева поиска и бинарных функций кучи. Вставки в декартово дерево может быть выполнены путем установки нового ключа как лист существующего дерева, выбирая приоритет для него, а затем выполняя вращение дерева операций по пути от узла к корню дерева , чтобы исправить все нарушения свойство кучи , вызванное этой вставкой; делеция , может также быть выполнена с постоянной величиной изменения к дереву , за которым следует последовательность вращений вдоль одного пути в дереве.

Если приоритеты каждой клавиши выбираются случайным образом и независимо друг от друга один раз каждый раз , когда ключ вставлен в дерево, в результате декартово дерево будет иметь те же свойства, что и случайного двоичного дерева поиска , дерева , вычисленной путем вставки ключей в случайно выбранной перестановки запуска из пустого дерева, с каждой вставкой оставляя предыдущую структуру дерева без изменений и вставить новый узел в виде листа дерева. Случайные двоичные деревья поиска были изучены гораздо дольше, и , как известно, ведут себя также деревьев поиска (они имеют логарифмическую глубину с высокой вероятностью); то же самое хорошее поведение переносится на treaps. Также возможно, как это было предложено Арагоном и Сайдел, чтобы изменить приоритеты часто используемые узлы, заставляя их двигаться к корню декартовы дереву и ускоряя будущий доступ к тем же клавиши.

Реализация

Реализуем все описанные выше операции. Здесь для удобства введены другие обозначения – приоритет обозначается prior, значения – key.

struct item {
	int key, prior;
	item * l, * r;
	item() { }
	item (int key, int prior) : key(key), prior(prior), l(NULL), r(NULL) { }
};
typedef item * pitem;

void split (pitem t, int key, pitem & l, pitem & r) {
	if (!t)
		l = r = NULL;
	else if (key key)
		split (t->l, key, l, t->l),  r = t;
	else
		split (t->r, key, t->r, r),  l = t;
}

void insert (pitem & t, pitem it) {
	if (!t)
		t = it;
	else if (it->prior > t->prior)
		split (t, it->key, it->l, it->r),  t = it;
	else
		insert (it->key key ? t->l : t->r, it);
}

void merge (pitem & t, pitem l, pitem r) {
	if (!l || !r)
		t = l ? l : r;
	else if (l->prior > r->prior)
		merge (l->r, l->r, r),  t = l;
	else
		merge (r->l, l, r->l),  t = r;
}

void erase (pitem & t, int key) {
	if (t->key == key)
		merge (t, t->l, t->r);
	else
		erase (key key ? t->l : t->r, key);
}

pitem unite (pitem l, pitem r) {
	if (!l || !r)  return l ? l : r;
	if (l->prior prior)  swap (l, r);
	pitem lt, rt;
	split (r, l->key, lt, rt);
	l->l = unite (l->l, lt);
	l->r = unite (l->r, rt);
	return l;
}

Неявный ключ

Обычное декартово дерево — это структура для множеств, каждый элемент которых имеет какой-то ключ. Эти ключи задают на этом множестве какой-то порядок, и все запросы к ДД обычно как-то привязаны к этому порядку.

Но что, если у нас есть запросы, которые этот порядок как-то нетривиально меняют? Например, если у нас есть массив, в котором нужно уметь выводить сумму на произвольном отрезке и «переворачивать» произвольный отрезок. Если бы не было второй операции, мы бы просто использовали индекс элемента в качестве ключа, но с операцией переворота нет способа их быстро поддерживать актуальными.

Решение такое: выкинем ключи, а вместо них будем поддерживать информацию, которая поможет неявно восстановить ключ, когда он нам будет нужен. А именно, будем хранить вместе с каждой вершиной размер её поддерева:

Размеры поддеревьев будем поддерживать по аналогии с суммой — напишем вспомогательную функцию, которую будем вызывать после каждого структурного изменения вершины.

не меняется, а вот в нужно использовать позицию корня вместо его ключа.

Про теперь удобнее думать как “вырежи первые элементов”.

Всё. Теперь у нас есть клёвая гибкая структура, которую можно резать как угодно.

Пример: переворот

Нужно за \(O(\log n)\) обрабатывать запросы переворота произвольных подстрок: значение \(a_l\) поменять с \(a_r\), \(a_{l+1}\) поменять с \(a_{r-1}\) и т. д.

Будем хранить в каждой вершине флаг, который будет означать, что её подотрезок перевернут:

Поступим по аналогии с ДО — когда мы когда-либо встретим такую вершину, мы поменяем ссылки на её детей, а им самим передадим эту метку:

Аналогично, эту функцию будем вызывать в начале и .

Саму функцию реализуем так: вырезать нужный отрезок, поменять флаг.

Небольшой рефакторинг

Реализация большинства операций всегда примерно одинаковая — вырезаем отрезок с \(l\) по \(r\), что-то с ним делаем и склеиваем обратно.

Дублирующийся код — это плохо. Давайте используем всю мощь плюсов и определим функцию, которая принимает другую функцию, которая уже делает полезные вещи на нужном отрезке.

Применять её нужно так:

Это работает в плюсах, начиная с .

Для простых операций можно даже написать лямбду:

Персистентность

Так же, как и с ДО, персистентной версией ДД можно решать очень интересные задачи.

Построим персистентное ДД. Тогда просто вызвав два -а, мы можем получить копию любой подстроки (указатель вершину), которую потом можно вставлять куда угодно, при этом оригинальную подстроку мы не изменим.

Можно в вершинах хранить полиномиальный хэш соответствующей подстроки. Тогда мы можем проверять равенство подстрок сравниванием хэшей вершин, полученных теми же двумя сплитами.

Чтобы полноценно сравнивать стоки лексикографически, можно применить бинарный поиск: перебрать длину совпадающего суффикса, и, когда она найдется, посмотреть на следующий символ.

Реализация почти такая же, как и для всех персистентных структур на ссылках — перед тем, как идти в какую-то вершину, нужно создать её копию и идти в неё. Создадим для этого вспомогательную функцию :

Во всех методах мы будем начинать с копирования всех упоминаемых в ней вершин. Например, персистентный начнётся так:

В ДО просто создавать копии вершин было достаточно. Этого обычно достаточно для всех детерминированных структур данных, но в ДД всё сложнее. Оказывается существует тест, который «валит» приоритеты: можно раскопировать много версий одной вершины, а все остальные — удалить. Тогда у всех вершин будет один и тот же приоритет, и дерево превратится в «бамбук», в котором все операции будут работать за линию.

У этой проблемы есть очень элегантное решение — избавиться от приоритетов, и делать теперь следующее переподвешивание: если размер левого дерева равен \(L\), а размер правого \(R\), то будем подвешивать за левое с вероятностью \(\frac{L}{L+R}\), иначе за правое.

Теорема. Такое переподвешивание эквивалентно приоритетам.

Доказательство. Покажем, что все вершины всё так же имеют равную вероятность быть корнем. Докажем по индукции:

  • Лист имеет вероятность 1 быть корнем себя (база индукции)
  • Переход индукции — операция . Любая вершина левого дерева была корнем с вероятностью \(\frac{1}{L}\) (по предположению индукции), а после слияния она будет корнем всего дерева с вероятностью \(\frac{1}{L} \cdot \frac{L}{L+R} = \frac{1}{L+R}\). С вершинами правого дерева аналогично.

Получается, что при таком переподвешивании всё так же каждая вершина любого поддерева равновероятно могла быть его корнем, а на этом основывалось наше доказательство асимптотики ДД.

Философский вопрос: можно ли декартово дерево называть декартовым, если из него удалить и \(x\), и \(y\)?

Реализация

Декартово дерево удобно писать на указателях и структурах.

Создадим структуру , в которой будем хранить ключ и приоритет, а также указатели на левого и правого сына. Указателя на корень дерева достаточно для идентификации всего дерева. Поэтому, когда мы будем говорить «функция принимает два дерева» на самом деле будут иметься в виду указатели на их корни. К нулевому указателю же мы будем относиться, как к «пустому» дереву.

Объявим две вспомогательные функции, изменяющие структуру деревьев: одна будет разделять деревья, а другая объединять. Как мы увидим, через них можно легко выразить почти все функции, которые нам потом понадобятся.

Merge

Принимает два дерева (два корня, \(L\) и \(R\)), про которые известно, что в левом все вершины имеют меньший ключ, чем все в правом. Их нужно объединить в одно дерево так, чтобы ничего не сломалось: по ключам это всё ещё дерево, а по приоритетами — куча.

Сначала выберем, какая вершина будет корнем. Здесь всего два кандидата — левый корень \(L\) или правый \(R\) — просто возьмем тот, у кого приоритет больше.

Пусть, для однозначности, это был левый корень. Тогда левый сын корня итогового дерева должен быть левым сыном \(L\). С правым сыном сложнее: возможно, его нужно смерджить с \(R\). Поэтому рекурсивно сделаем и запишем результат в качестве правого сына.

Split

Принимает дерево и ключ \(x\), по которому его нужно разделить на два: \(L\) должно иметь все ключи не больше \(x\), а \(R\) должно иметь все ключи больше \(x\).

В этой функции мы сначала решим, в каком из деревьев должен быть корень, а потом рекурсивно разделим его правую или левую половину и присоединим, куда надо:

Пример: вставка

и сами по себе не очень полезные, но помогут написать все остальное.

Вот так, например, будет выглядеть код, добавляющий \(x\) в дерево.

Пример: модификация для суммы на отрезке

Иногда нам нужно написать какие-то модификации для более продвинутых операций.

Например, нам может быть интересно иногда считать сумму чисел на отрезке. Для этого в вершине нужно хранить также своё число и сумму на своем «отрезке».

При и надо будет поддерживать эту сумму актуальной.

Вместо того, чтобы модифицировать и , и под наши хотелки, напишем вспомогательные функцию , которую будем вызывать при обновлении детей вершины.

В и теперь можно просто вызывать перед тем, как вернуть вершину, и тогда ничего не сломается:

Тогда при запросе суммы нужно просто вырезать нужный отрезок и запросить эту сумму:

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: