Начал изучать, возникла пара вопросов. Сдал эту задачу, по времени не сильно отличается от декартова. Так ведь и должно быть? Или может у меня не очень эффективная реализация? Второй вопрос по неявному дереву. Операцию merge по-моему можно делать как в обычном дереве, а вот если в обычном дереве split выполняется через splay, то здесь так нельзя. Нужно ли его делать, как в декартовом? Не ухудшит ли это время работы?
UPD: В неявном все как и в обычном, с этим разобрался, спасибо. Тогда другой вопрос. На вики написано, что эту жуть легко персистентной сделать. Может кто знает как?
В дереве по неявному ключу split делается через splay, как еще его делать?
По поводу времени работы — в статье Тарьяна и Слейтора показано, что к каждой вершине, к которой ты касаешься, нужно применять splay, тогда будет амортизировано O(logn) на операцию.
Просто если делать через splay, как в обычном, то вот что получается:
пусть было дерево (это я не неявные ключи расставил, а просто данные сопутствующие)
1
/ \
4 5
/ \
2 6
\
3
Пусть мы теперь хотим по ключу 2 отрезать (неявному разумеется), т.е на выходе должны получить в качестве левого дерева 2 — 3. Если через сплей, то найдем 2 и от нее его сделаем, получится такое дерево:
2
\
1
/ \
4 5
/ \
3 6
В левую часть ответа пойдет 2, а в правую 1 и ее поддерево.
Ты сделал splay неправильно, посмотри сдесь: http://www.cs.princeton.edu/courses/archive/fall07/cos521/handouts/self-adjusting.pdf
страница 656, рисунок (b) zig-zig
Блин, не то дерево из тетради перерисовал. Вот такой результат:
2
\
4
/ \
3 1
\
5
\
6
Если резать по неявному ключу 2, то мы должны применить splay к елементу 3, а не 2.
Точно, спасибо.
Неявное тоже медленнее декартова немного.
Скорее всего где-то неоптимально написано, или забыли где-то сделать Splay. Хотя по отдельности оно не сильно выигрывает. А вот в более сложных структурах.
Тоже хочу изучить эту структуру, но столкнулся с трудностями:
Кто-то может обьяснить как обрабатывать запросы, связаные с отрезками? И возможно ли это? Например интересно было бы услышать как делать эту, или эту задачи. Хоть по тематике эти задачи даются как для дерамиды, но так как неоднократно писалось что сплей умеет строго больше декартки, то интересно было бы узнать решение с использованием именно сплей дерева.
По идее реверс такой же, как в декартовом: высплитили, реверснули, вмержили. Единственное — нужно быть очень аккуратным с push'ами во время splay.
Наверно меня сейчас страшно заминусуют, но видимо я не могу понять то что для каждого в этой ветке является элементарным. Как хранить в дереве элементы, при этом как-то упорядоченые по их расположению на отрезках и как при сплеях не потерять эту упорядоченость?
А в чем проблема? Splay устроен так, что не меняет обход дерева в смысле порядка вершин даже.
Аккуратность заключается в том, что надо сделать push для всех предков (начиная с корня, это важно) перед тем, как делать Splay. На время оно не влияет, потому что явно посмотрели на потенциал, он не поменялся от этих операций. А время на них просто увеличивает константу при реальном времени каждой отдельной операции.
Offtopic: а что это умеет сплей, чего не умеет декартово дерева?
Точно знаю, что умеет декартово, но не умеет сплей: одновременный доступ на чтение из нескольких потоков. Splay требуется каждый раз перестраивать, а декартову это нужно только при изменениях.
Амортизироваться в link-cut :)
Где-то слышал, что оно примерно для этого и было придумано.
На самом деле link-cut это не единственная надстройка. Просто она единственная с которой было не лень разобраться кому-то кто разбирался с Splay и связанным из российских олимпиадников.
P.S. А придумано оно было ради того, чтобы сделать еще одну надстройку над lct и получить быстрый поток.
Так ты же и говорил когда-то:)
Аватар в тему, спасибо. Как ни странно, конкретных задач на это с того времени так и не узнал (кроме упомянутого и тут, и там lct).