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

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

292A - SMSC

Для каждого момента i времени запомним количество сообщений z[i], которое нужно отправить в момент времени i. Теперь пройдем по каждому моменту времени от 1 до 106, поддерживая текущий размер очереди sz. На каждой итерации попробуем уменьшить размер очереди на 1, то есть выполним sz = max(sz - 1, 0), затем прибавим сообщения, которые нужно отправить в эту секунду, то есть выполним sz = sz + z[i]. На каждом шаге будем обновлять максимальное значение очереди и текущее время, если sz > 0. После выполнения цикла, если в очереди остались неотправленные сообщения, то нужно еще раз обновить ответ.

292B - Network Topology

В этой задаче нужно было посчитать степени каждой вершины и найти ответ. Замечу, поскольку n >  = 4, m >  = 3 и граф связный, то ответ однозначный.

1) все степени 2 и у двух вершин степень 1 — шина.
2) все степени 2 — кольцо
3) все степени 1 и у одной степень  > 2 — звезда
4) иначе неизвестно

292C - Beautiful IP Addresses

Задача решается перебором. Для начала переберем сколько цифр в каждом четверти мы возьмем, например AAA.B.CC.DDD. Теперь посчитаем количество символов в этой строке (AAABCCDDD) и переберем цифры на первой половине этой строки (поскольку строка должна быть палиндромом, то вторая половина однозначно восстанавливается). После этого проверим, что такой ip-адрес является корректным и содержит правильный набор цифр. Если ip-адрес удовлетворяет всем условиям задачи, то добавим его к ответу.

292D - Connected Components

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

У этой задачи много правильных решений. Изначально планировалось решение, которое предподсчитывает частичные dsu (структура данных disjoint set union) на префиксах и на суффиксах, то есть массивы ldsu[M][N] и rdsu[M][N]. После этого на запрос [lf ; rg] легко ответить за время O(N·A - 1), если объединить множества ldsu[lf - 1] и rdsu[rg + 1], где A - 1 -- обратная функция Аккермана (константа от dsu).

292E - Copying Data

У этой задачи много правильных решений. Изначально предполагалось решение, использующие корневую эвристику. Разобьем все запросы на sqrt(m) блоков. Будем поддерживать текущий массив b в виде отрезков в массиве z, который хранит четверки (lf, rg, type, start), где lf, rg — отрезок индексов массива b, type — 0 или 1, означающее из какого массива взяты числа для этого отрезка, start — позиция начала этого отрезка в массиве типа type.

На запросы будем отвечать в тупую, то есть честно пересчитывать как изменится массив z от запроса копирования и отвечать на запросы значения в позициях. Однако, каждые sqrt(m) запросов будем сливать данные из массива z в массив b, для того чтобы сам массив z сильно не разрастался.

Есть простое решение с деревом отрезков, которое умеет делать покраску на отрезке. Пусть пришел запрос копирования [lf ; rg], , тогда покрасим отрезок запроса [lf ; rg] в цвет, равный номеру запросу. Все запросы будем сохранять. Пусть пришел запрос значения в позиции x, тогда найдем цвет в дереве в этой позиции. Если такого цвета нет, значит мы находимся в исходном массиве b (выведем b[x]), иначе посчитаем смещение dx от начала этого запроса до нашей позиции x и выведем a[x + dx].

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

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

В D можно поделить рёбра на P ~ 20 блоков, и для каждой пары (префикс, суффикс), состоящей из целого числа блоков, посчитать DSU. После этого получается что-то типа O(K * M * C) где C мелкая константа копирования массива.

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

    Можно сделать сразу за N^2 если просто выбросить все ребра, которые не входят в остов в порядке инпута и в обратном инпуту порядке. Интереснее, есть ли решения быстрее.

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

      Сорри, я имел ввиду O(K * M). У тебя выходит O(N * M) , вообще супер!

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

        У меня выходит O(N^2*A^-1 + K). После того, как осталось 2N ребер, различных запросов не более, чем N^2.

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

          Так запросов всего 2 * 104 что на порядок меньше N2. Можно каждый запрос втупую.

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

А можно ли Е решить декартовым деревом? Склеить 2 массива, а потом вырезать по 2 куска и 1 вставлять на место другого.

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

    Да только нужно еще дерево сделать персистентным)))

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

      И получить ТЛ 30 :)

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

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

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

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

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

            Интересно, а что за "оптимизация"?

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

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

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

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

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

                  не мог бы ты объяснить почему будет ТЛ?

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

                  Если выставлять приоритет рандомом, то скоро начнёт нарушаться свойство декартового дерева. При merge это выльется в то, что корень будет выбираться равновероятно из двух вершин. И если сделать много merge подряд вида "большое дерево + вершина", то получится бамбук.

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

                  Впрочем, возможность построить тест зависит от конкретной задачи. Например, в задаче memory (операции с массивом "сумма на отрезке" и "скопировать отрезок в другой, как memcpy") тест строился вообще на халяву — куча средних по размеру копирований.

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

                На сколько я знаю хорошей практикой является вообще не хранить приоритет, т.к. он используется только в мердже, а выбирать какой узел будет новым корнем с вероятностью зависящей от размера поддеревьев.
                Кстати меня это очень забавляет, особенно персистентное декартово дерево по неявному ключу, ведь в нём не хранится ни X ни У))

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

                  А можно ли избавиться от приоритетов в неперсистентном дереве таким же трюком или это будет плохо работать?

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

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

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

                  Ага, выходит что персистентное декартово дерево не только не декартово (ни X, ни Y не хранятся), но и не дерево (ссылки на сыновей образуют ациклический ориентированный граф, а не дерево).

                  Персистентное недекартово недерево.

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

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

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

    Мне кажется не получится, так как такое решение использует квадрат памяти.

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

      Памяти-то O(NlogN), но константа большая.

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

        caustique ничего не говорил про персистентность)

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

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

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

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

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

              Тогда чем это отличается от персистентного декартова дерева?

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

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

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

    Задачу Е надо просто решать мапой.

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

      Можете на словах объяснить свое решение, пожалуйста? Из кода ничего не понял:(

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

        У меня кода было больше, но идея примерна такая же. В сете хранятся отрезки (L, R, startPosA) отрезки сортируются по R, L равно R — 1 предыдущего отрезка, так что её можно и не хранить в принципе. b[L] = a[startPosA], b[L + 1] = a[startPosA + 1], ... .При обработке запроса на интервале (L, R) нужно поудалять из сета все отрезки из этого интервала, крайние пересекающиеся с ним нужно уменьшить, чтобы пересечения небыло. Потом добавляем наш отрезок (L, R). Каждый раз мы увеличиваем число отрезков максимум на 2, поэтому несмотря на то что в какой-то момент мы сможем удалить из сета O(n) отрезков за одну операцию, всего будет O(n) обращений к сету.

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

          Спасибо, понял, интересное решение — буду как-нибудь такую идею следующий раз использовать.

          Только не понял маленькую деталь — почему количество отрезков увеличивается максимум на 2, а не на 1? Казалось бы, добавляем только отрезок [L, R] — остальные либо укорачиваем, либо удаляем.

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

            Либо удаляем середину, и оставляем два края.

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

              -1+2=1, то есть увеличение произошло всего на 1 отрезок

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

                Был один отрезок [0..10]. Добавляем отрезок [4..6]. Получилось три отрезка: [0..4], [4..6], [6..10].

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

                  Спасибо за подробное объяснение, теперь понял:)

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

Хреново вы отловили решения за O(nm) в D. Вот зачем такие подгоны делать?

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

    Проведи свой чемпионат и сделай лучше ;)

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

      надеюсь неудачные ограничения в D не испортили идеи придуманных задач, спасибо Сергей)

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

        Дэшка прикольная, хоть и не удалось мне ее сдать на контексте, отослав решение, как в разборе) А Е позволила познать новую идею) Спасибо

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

    Мне уже интересно увидеть то решение в D, над которым авторы долго потели, но так и не заставили его залезть в ТЛ.

    Ведь, на самом деле, там еще и с неплохим запасом проходит.

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

      Ставь фильтр ТЛ по задаче Д и выбирай любое)

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

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

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

          Кстати было бы прикольно если бы можно было хакать чужие решения после раунда, конечно никуда это не учитывая. Потому что мне реально интересно пару тестов попробовать на чужих решениях. А на своем компе это уже будет не совсем адекватное сравнение с учетом таких зазоров.

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

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

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

              А оказывается, что можно, сам недавно узнал — можно прикрепить код генератора теста.

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

Кто-то может мне обьяснить, почему у меня по Е SQRT-декомпозиция работает чуть ли не быстрее, чем у других RMQ?

У меня 0.218с; нормальные решения с RMQ укладываются в 0.2, но даже на С++ большая часть решений с какими-то более сложными, чем декомпозиция, структурами работает медленней.

У меня на запрос второго типа ответ за О(1), обработка запроса первого типа — 3*SQRT(N). Т.е. что-то около 1000 операций.

Более того, сабмит с размером блока 50 (что дает нам около 2000 операций на запрос) проходит за 0.265с.

Тесты весьма удачные, или декомпозиция действительно настолько быстро летает за счет простоты операций?

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

    SQRT декомпозиция в кэш хорошо укладывается, от этого и все плюшки, насколько я знаю.

»
12 лет назад, # |
Rev. 3   Проголосовать: нравится -21 Проголосовать: не нравится

Может посоревнуемся, у кого получится более быстрое решение D, из тех что за квадрат и вообще не должны укладываться в 2 секунды?

Я пока что нашел решение NVAL3549348 за 1.437 с.

При этом передо мной система codeforces немного в долгу за не полученный из-за моего собственного фэйла красный, и поэтому на моих посылках идентичное решение (3549806, 3549809) отработало сначала за 1.281, а потом за 1.265.

Если отбросить немного бредовую идею с кармой из-за про**аного 31 места, то получаем другой вопрос — почему система codeforces один и тот же код тестирует с погрешностью в 0.17 секунд?

На фоне решений, которые прошли сегодня за 1.984 (или даже за 2.000 у кого-то? или нету таких?), это вызывает улыбку) А с учетом того, что некоторые просто переслали в архив свое решение с контеста, и оно получило АС за 1.984 или 2.000, при TL на контесте — широкую улыбку))))

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

    По-моему в этом конкурсе у меня есть шансы. Мое решение уложилось в пол секунды. Я сам в шоке, я молился, чтобы оно влезло в две.

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

    Ну по этому поводу Михаил как-то рассказывал, что во время соревнований тестирование сразу двух решений может производиться на одном ядре. Из-за этого время оценивается немного неправильно, но если решение на каком-то тесте получает TL, то оно перетестируется на отдельном ядре.

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

      Что, имхо, не идеально. Теоретически, если у меня в переборе стоит отсечение по времени, то я вместо TL и OK (на последующем перетестировании) могу получить WA, хотя "на самом деле" решение заходит.

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

    BFS получается быстрее вроде — 3553590 за 1031 мс.

    Правда почти идентичное решение 3553789 работает за 1609 мс — погрешность больше полсекунды, что многовато.

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

can someone translate 292-D in english

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

can someone translate tutorial of 292-D in english

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

    English Translation-

    The restrictions in the problem were not very successful and provoked a solution to be written in a square; we tried not to let such solutions pass as much as possible.

    This task has many correct solutions. Initially, a solution was planned that calculates partial dsu (data structure disjoint set union) on prefixes and suffixes, that is, arrays ldsu [ M ] [ N ] and rdsu [ M ] [ N ] . After that, the request [ lf ; rg ] it is easy to answer in time O ( N · A  - 1 ) if we combine the sets ldsu [ lf  - 1] and rdsu [ rg  + 1] , where A  - 1 is the inverse Ackerman function (constant from dsu).

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

I didn't understand the 292E (copy data) solution. Can someone help me out.