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

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

25 февраля 2012 года в 12:00 по Москве состоится Восьмая индивидуальная олимпиада на сайте http://neerc.ifmo.ru/school/io/index.html . Задачи теперь с feedback. Подробнее будет указано в условие задачи(что-то мне подсказывает что будет работать только через web-client). После окончания олимпиады предлагается здесь обсудить задачи.

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

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

Как решалась D на 100?

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

    D — это поздача задачи H с открытой олимпиады и немножко случаев. Только 1 часа на неё мне внезапно оказалось мало :)

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

      Если кратко: найдём двумя указателями касательные к многоугольнику для каждого человека. Если дверь лежит по эту сторону, то ответ — расстояние до неё, если по другую — переберём, через какую сторону пойдём, добавим длину пути по соответствующей касательной, а расстояние между вершинами многоугольника легко вычисляется за O(1) (с линейным предподсчётом).

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

Расскажите решение всех задач, пожалуйста.

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

Сильно интересует 6-й тест задачи D, первой группы.

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

Как решать B, C не в лоб? Полконтеста над ними думал, так ничего не придумал. Есть идея в С решать деревом отрезков с хранением подмассива в вершине? Подскажите если кто умеет быстро решать...

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

    B, кратко идея за линию: 1)Порядок операций неважен 2)Один человек является концом максимум для одного запроса 3)Храним ответ в двусвязном списке 4)Научимся решать для подотрезка (в изначальном массиве) за линию. Если в первый элемент — не крайний, свелись к меньшему и дописали в начало. 5)Если первый элемент — крайний для чего-то, свелись к двум меньшим (внутренность и остаток). Теперь поменяли у внутренности местами начало и конец. У нас изменится смысл next/prev, ну да ладно — он однозначно восстанавливается при обходе. Сконкатенировали внутренность и остаток.

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

    Б видимо можно так: у нас не играет роли в каком порядке мы делаем реверсы

    ну тогда отсортим отрезки по длине (чтобы после реверса границы больших отрезков оставались прежними ai = apos bi = bpos и будем делать обычным декартовым

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

    C — решение за (можно чуть проще за ). Посмотрим на кандидатов, которых больше . Таких мало — предподсчитаем для них суммы на префиксах и для каждого запроса прорелаксируем "в лоб". Теперь разберёмся с остальными. Сгруппируем запросы в "корзины" по левым границам, каждая корзина захватывает бюллетеней. Отсортировали запросы в каждой корзине по правой границе. Теперь двумя указателями двигаем отрезок: правый двигается только вправо, а левый — не более, чем на . За O(1) пересчитываем количество каждого кандидата и еще за O(1) мы можем пересчитывать количество кандидатов с таким количеством голосов. Так как мы уже учли кандидатов, у которых более голосов, то мы можем "в лоб" за прорелаксировать для каждого запроса.

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

      не очень понятно, что значит левый указатель двигается не более чем на N * sqrt(n)

      p.s. насколько я понял у вас N — количество бюллетеней, n — количество запросов?

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

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

        Они одинаковы, поэтому всё равно. Везде стоит читать как n

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

          Спасибо, за подробное объяснение =) насколько я понял получается что в каждой "корзине" мы храним все запросы начинающиеся в текущем блоке длины sqrt(n), сортируем запросы по возрастанию правых концов и получается наш правый указатель в каждом блоке пройдет суммарно не более N. И тут же появляется вопрос как быстро брать ответ? Я только понимаю как set'ом или деревом отрезков по сжатым кандидатам? Можно ли как-нибудь за O(1) или я что-то не так понял?

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

            Да, всё так. Фишка в том, что если будет set или дерево отрезков — будет долго. Зайдёт, наверное, но можно за O(1).

            Изначально сожмём координаты. Заметим, что никакой кандидат не встретится более раз (иначе мы его обработаем в предподсчёте). Храним две вещи: массив (кандидат => сколько раз был, длины n) и обратный к нему (сколько раз был => количество таких кандидатов, длиной ). Пересчитываются оба за O(1). Ответ извлекается за для каждого запроса — пробежались по обратному массиву. Итого — избавились от логарифма set'а/дерева отрезков.

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

      А заходило тут? Я так понимаю, это SQRT-декомпозиция запросов + куча?

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

        Я сначала написал такое, только не с кучей, а с деревом отрезков. Работало 10 сек примерно.

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

      А зачем отдельно считать для тех кого больше корня? Можно-же пересчитывать за О(1) максимум если число только на 1 увеличивать/уменьшать.

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

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

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

Отлично — первые 47 минут контеста решал не те задачи а в А не дал unsigned long long!

Насколко я понимаю, вот результаты (но не всегда почему-то показывает)

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

оказывается в С и Д тесты последней группы оцениваются пропорционально пройденому... как я так не прочитал это(