Нужен аналог std::set::lower_bound/upper_bound в C#. Например, для решения чего-нибудь такого: timus 1414
Погуглив, не нашел аналога, работающего за логарифм. SortedSet — ближайший родственник std::set — ничего подобного не умеет. Как будто бы остается только самому дерево писать.
Но на всякий случай спрошу еще здесь: кто-нибудь знает, можно ли это сделать?
А можно развернуть, что требуется? Чем вам List.BinarySearch не подойдёт?
Нужно поддерживать еще и добавление в множество новых элементов онлайн.
Ну строго говоря, можно костыльно учитывать добавление-удаление :)
Ну а надо не костыльно, а за логарифм.
У SortedSet есть метод GetViewBetween. Это именно то, что нужно.
Проверил — что-то очень быстро при увеличении N время работы растет. Оно точно за логарифм работает?
Я его декомпилировал Рефлектором в свое время. Насколько я вижу — вроде логарифмический.
Правда, там еще потом какой-то
VersionCheckImpl()
делается...UPD1: В общем, вот весь остальной код.
UPD2: Судя по тому, что он зачем-то так по-дурацки считает количество вершин в получившемся поддереве — таки линейный... Брр, неужели?
UPD3: Вот этот код работает за 32 секунды. Отвратительно.
Можно написать сжатый бор и сдать 1414. Не гарантирую, конечно, что сжатый бор пишется сильно быстрее собственного set'a, но и такой метод имеется. :)
Скорее всего, можно так сделать, правда это долго пишется. Затем создаем SortedSet, указав в качестве параметра экземпляр класса MyComparer, теперь чтобы найти lowerbound x, делаем Reset(), затем SortedSet.Contains(x), и нужно значение лежит в поле int? LowerBound.
Понимаю, что тема старая, но раз уж её подняли... Майкрософт об этом просят ещё с 2008-го года: http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/6776d660-ffa2-4174-8b91-a725c5265d2c/
Но чёт не видно подвижек пока что. Сам об этой особенности знаю, поэтому видя задачки, требующие этих вот bound-ов матерясь и кряхтя пересаживаюсь на c++, например из недавнего в задаче про антисоциальных пассажиров поезда из отборочного Russian Code Cup пришлось.