Блог пользователя riadwaw

Автор riadwaw, 12 лет назад, По-русски

Подкиньте, пожалуйста задачу(и?), где СНМ может стать узким местом.

Хочется проверить, насколько медленнее писать без одной из эвристик, ну и вообще попробовать разные их комбинации.

Видимо, меня не совсем поняли, хотелось просто безидейную задачу, где заваливают "плохие" СНМ. Впрочем, кому-нибудь как сборник задач, наверно, пригодится

  • Проголосовать: нравится
  • +5
  • Проголосовать: не нравится

»
12 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

Если я Вашу просьбу правильно понял, то вот пример такой задачи.

  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Господа минусующие, объясните свою логику, будьте любезны :).

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      По крайней мере, эту задачу можно и без снм решить. Пример не совсем удачный

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Возможно. Вообще-то да, задача больше интересна с точки зрения "увидеть СНМ и правильно его закодить".

»
12 лет назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится
  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится +8 Проголосовать: не нравится

    Сложилось такое впечатление, что задачи с персистентными структурами делает только Сергей Копелиович :) А не подскажете, может вы еще знаете какие-нибудь задачи на online-judge на персистентные структуры? Хотелось бы порешать такие задачи.

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится -13 Проголосовать: не нравится

      Ммм… На ПТЗ последних ещё была интересная задача на персистентный СНМ. Там добавляли/удаляли ребра из графа и нужно было отвечать на запросы о связности. В основном все делали sqrt декомпозицию, но ИТМО#1 сделали честное решение)

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        А персистентный СНМ поможет удалять произвольные ребра? Могут же возникнуть конфигурации, которые раньше не встречались.

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Там надо правильно применять. Каждое ребро появляется на каком-то отрезке. Деревом отрезков его можно разбить на лог кусков. И тогда обходя дерево отрезков ничего более страшного чем соеденить/разъеденить как было множества делать не надо.

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится +8 Проголосовать: не нравится

        Обращу внимание, что хотя в этот раз задача была не он Burunduk1 за год до этого она была от него.

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
            Проголосовать: нравится +1 Проголосовать: не нравится

          От себя добавлю, что hos.lyric уже улучшил мою идею (Klog^2K) до KlogK. Там вообще нет СНМ :-)

          А еще, если интересны подобные фичи, советую почитать похожую идею в статье Eppstein-а Dynamic MST, Offline Solution

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        там было не персистентное снм, а просто стэк порядка логарифма снм-ов... это в разы проще

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Чем в разы проще? И то и то адекватно делается только dfs'ом по версиям в оффлайне.

          • »
            »
            »
            »
            »
            »
            12 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            эм... нет... я делал в этой задачке поддержку снм онлайн именно за счёт того, что их мало

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится +4 Проголосовать: не нравится

      Например:

      Persistent-Stack — олимпиада ЛКШ :-)

      Persistent-Queue — один из контестов Андрея Станкевича в Петрозаводске.

      Persistent-Treap — на это были задачи в последнем Петрозаводске (контест не помню)

      Persistent-Lists-With-Merge — мой последний контест в Харькове.

      Правда вот на Online Judge почти все они отсутствуют. Но чтобы порешать, обычно достаточно достать тесты и протестить у себя локально :-) Если нужны тесты, пишите в личку.

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится

      http://www.codechef.com/problems/GENETICS Тут можно сдать персистентное декартово дерево

  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится +8 Проголосовать: не нравится

    Возможно нубский вопрос. А как писать персистентный СНМ?

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Хранишь rank и parent в персистентных массивах (читай: в персистентных деревьях отрезков). Сжатие путей выполнять не стоит — асимптотику оно не улучшит. Реализовывать объединение через рандом — тоже, см. тест ниже.

      • »
        »
        »
        »
        12 лет назад, # ^ |
        Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Что хочешь: сумму/минимум/вообще ничего.

          • »
            »
            »
            »
            »
            »
            12 лет назад, # ^ |
              Проголосовать: нравится +3 Проголосовать: не нравится

            забавно)) я пишу персистентный массив так, что промежуточных вершин нет вообще :) можете показать как вы реализовываете персистентный массив?

            • »
              »
              »
              »
              »
              »
              »
              12 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              вы тоже объясните, как? Пожалуйста

              • »
                »
                »
                »
                »
                »
                »
                »
                12 лет назад, # ^ |
                  Проголосовать: нравится +13 Проголосовать: не нравится

                у i-ой вершины сыновьями являются вершины с номерами 2*i и 2*i+1.
                массив — 1 2 3 4 5
                у 1 сыновья 2,3
                у 2 сыновья 4,5
                у остальных вершин нет сыновей.
                получается, что промежуточных вершин нет :)

»
12 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
»
12 лет назад, # |
  Проголосовать: нравится +9 Проголосовать: не нравится

Пример задачи, у меня там ТЛ был с плохой реализацией СНМ. Миллион вершин, как не крути.

  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Спасибо, это видимо как раз, что нужно, мое правда там не тормозило, зашло за 1.8/5c

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      У меня там падали реализации без одной из двух стандартных эвристик (т.е. как решение без подвешивания менее высокой к более высокой, так и решение без сжатия путей). С ними меньше секунды.

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Ну вообще без эвристик не интересно все же))

»
12 лет назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится

СНМ — Система Непересекающихся Множеств. DSU — Disjoint Set Union. Мне одному пришлось пройти к задачам, чтобы понять о чем вопрос? Сокращение DSU я бы понял, а СНМ вообще не понял, и не понял что по русски написано.

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится -37 Проголосовать: не нравится

    Аналогично. Огромное спасибо, что написали, я бы так и не понял. Зашел сюда как раз что бы ответить на вопрос, что такое СНМ

»
12 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

http://informatics.mccme.ru/moodle/mod/resource/view.php?id=671

Далее: Структуры данных --> Cистема не пересекающихся множеств

  • »
    »
    12 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    О!

    Говорят, ты валил СНМ, в котором подвешивание с rand()'ом. Правда ли это? Не подскажешь чем?) Ну и про прямое подвешивание, которое я обычно пишу тоже интересно (i.e dsu[get(a)]=get(b);)

    • »
      »
      »
      12 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      for i=1..n-1 : Join(i,i+1)

      Кстати, ты мне напомнил еще одну хорошую задачу, где принципиально, чтобы СНМ работало быстро:

      Зимние всероссийские сборы 2010, 5 декабря 2010, bridges.

      Краткое условие: нужно добавлять ребра в граф и после каждого запроса говорить "сколько сейчас мостов". Собственно, тогда первый раз и завалил :-)

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Я имел ввиду, что сжатие путей есть, а подвешивание такое, как раз. На таком тесте будет летать:)

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Я предположил, что у меня задача о персистентном СНМ ТЛится именно из-за рандома. Теперь все окончательно понятно.

    • »
      »
      »
      12 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится

      Кстати, если автор тестов не изверг, я бы сам писал реально быстрый СНМ так:

      Get(a) : return a == p[a] ? p[a] : (p[a] = Get(p[a]))
      Join(a, b) : p[Get(a)] = Get(b)
      

      Это уже в худшем случае работает аморатизированно за O(logN)

      Чтобы работало принципиально дольше чем за O(1), нужно строить специфические тесты.

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Ты же нам где-то давал задачу такие тесты строить.

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

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

          • »
            »
            »
            »
            »
            »
            12 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            По моему A0-ЛКШ. Что в том году вобщем-то эквивалентно.

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Если автор тестов не ты ?:)

        Не подкинешь идею таких тестов?)

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

          Про авторов тестов: в общем, просто опробуй мой вариант на существующих задачах :-)

          Идея теста: нужно много раз делать p[Get(v)] = new Vertex, где v — текущая самая глубокая вершина. Утверждается, что если изначально ничего нет, то N Get-ов сработают за Theta(NlogN) операций.

      • »
        »
        »
        »
        12 лет назад, # ^ |
          Проголосовать: нравится -8 Проголосовать: не нравится

        А что надо сделать чтобы СНМ реально работал за О(1)? достаточно ли в "Join" добавить эвристику по количеству вершин в множестве?

        • »
          »
          »
          »
          »
          12 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится

          Предлагаю все-таки прочесть википедию: СНМ

          От себя добавлю, что Fredman and Saks в 1989 показали, что лучше, чем \alpha(n) не бывает (взято с eng-wiki).

          • »
            »
            »
            »
            »
            »
            12 лет назад, # ^ |
              Проголосовать: нравится -16 Проголосовать: не нравится

            ну это понятно, просто как то сложилось, что многие считают, что обратная функция Аккермана принимает очень маленькие значения (<= 4) для всех чисел которые влазят в стандартные типы, поэтому считают, что О(1). Вопрос состоял в том, что как реально приблизиться к этой асимптотике O(alpha(n))

            • »
              »
              »
              »
              »
              »
              »
              12 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              Это же в Кормене рассказано.

            • »
              »
              »
              »
              »
              »
              »
              12 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              Ещё раз: приближаться не надо, мы уже там. Можно открыть английскую википедию. Там и обе эвристики (о рангах и о сжатии путей) с объяснением, и в конце написано, что:

              1. СНМ с обеими эвристиками работает за O(α (n));

              2. Это время работы неулучшаемо, то есть реальной оценки O(1) добиться нельзя.