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

Автор yarrr, 12 лет назад, По-русски
  • Проголосовать: нравится
  • +59
  • Проголосовать: не нравится

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

12:00 UTC, 12/12/2012: The most beautiful time of the year :D

Good luck :D

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

Рейтинг: 1499. Хочу обратно в жёлтые! ^_^

UPD: как решать хард?

UPD2: И всё-таки я жёлтый ^_^

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

<************ мой хард упадет из-за того, что я написал в одном месте n а не a.size() АААААА

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

Как, как все решают хард на 660+? Я совсем отупел и там есть какая-то простая для придумывания динамика?

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

Как решать медиум?

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

    Переберем, сколько до k-го шага было циклов "по 3", сколько "по 2", и остается сколько-то "по 1". Это медленное решение за n^2. Ну и теперь свернем часть сумм чтобы стало за n или за 1.

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

    Перебираем количество красных шариков x, взятых до k-того взятого шарика, и смотрим на количества взятых зелёных и синих y и z до k-того взятого шарика. Ясно, что y + z = k - x - 1. Дальше разбираем 3 случая:

    1. y, z < x;
    2. y = x, z < x или y < x, z = x;
    3. y = x, z = x.

    В каждом случае нужно посчитать, сколькими способами можно построить y и z, а также дополнить каждый из трёх цветов с помощью разных формул, за константное время.

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

    Я решал так: перебрал номер итерации алгоритма когда у нас убирается k-ая штука и при этом она красная. Тогда я знаю сколько было убрано других до. Ну и дальше разбор случаев в стиле: 1) оба цвета ещё остались после этой итерации 2) все шары других видов убраны до этой итерации 3) Один не красный исчезает второй остается. 4) когда может быть что не красные могут быть либо убраны до этой итерации, либо остается ещё 1 ровно 1 цвет.

    И в каждом случае можно очень легко посчитать.

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

    Можно динамикой [порядковый номер шара, который сейчас вылетит][маска цветов, которые ещё не вылетели][номер шага программы]

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

      Это можно немного упростить, если разрезать процесс не на шаги по одному шарику, а по одному циклу программы. Тогда останется всего два состояния — сколько шаров уже убрали и какая маска шаров была в последнем слое, переход — перебрали следующий слой.

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

      Я делал похожим образом — перебирал вид этой маски в момент перед взятием k-го шарика и суммировал ответы для каждой возможной маски.

      Если зафиксировать маску в этот момент, то ответ для нее — это произведение числа способов оставить такую маску из n-k+1 шариков (биномиальные коэффициенты) на число способов убрать первые k-1 шарик так, чтобы прошло полное число "циклов" (т.е. проверок каждого из 3 цветов) и маска получила зафиксированный нами вид (это решаем динамикой).

      А в динамике можно считать dp[balls_added][mask_of_colors] — будем имитировать процесс с конца (добавлять шарики), можно за 1 итерацию прибавлять целый цикл проверок, тогда переход в динамике:

      dp[balls_added+count(new_mask)][new_mask]+=dp[balls_added][old_mask]*is_submask(new_mask,old_mask)

      Здесь count считает число единичных битов, а is_submask проверяет, является ли маска подмаской другой маски.

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

    Я решал динамикой :)

    dyn[i][0] означает число способов взрывать шарики так, что на i-м месте стоит красный и что у нас могли ещё остаться шарики трех цветов (т.е. прежняя последовательность выглядит как rgbrgb...rgbr)

    dyn[i][1] означает число способов взрывать шарики так, что на i-м месте стоит красный и у нас могли остаться шарики только двух цветов.

    dyn[i][2] — то же самое, но остались только красные шарики

    dyn[i+3][0] = dyn[i][0];
    dyn[i+2][1] = dyn[i][1] + dyn[i][0]*2;
    dyn[i+1][2] = dyn[i][2] + dyn[i][1] + dyn[i][0];
    

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

    ans = dyn[k][0]*(n-k+1)*(n-k+2)/2;
    ans += dyn[k][1]*(n-k+1);
    ans += dyn[k][2];
    
  • »
    »
    12 лет назад, # ^ |
      Проголосовать: нравится +8 Проголосовать: не нравится

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

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

      А вот я как раз пофейлился:(

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

      Это очень легко протестить локально. Мне кажется, многие просто написали брутфорс и сравнили.

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

        Я так и сделал под конец. А в процессе написания всё поймалось сэмплами.

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

А как решать 850?

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

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

    Переберем номер бита, на котором впервые префикс какого-то числа стал меньшим, чем его максимальное допустимое значение. Для всех предыдущих битов должно выполняться условие, что их xor во всех числах из инпута совпадает с соответствующими битами числа n. Чтобы найти количество способов поставить текущий бит, можно воспользоваться следующей динамикой:

    f(i, j, k) -- количество способов выбрать текущий бит и все следующие за ним в первых i числах, при условии что xor текущего бита в них равен j, а k говорит, встретилось ли нам уже число, для которого мы выбрали 0, хотя текущий бит в нем 1. Эта динамика считается за O(m), где m -- количество чисел.

    Получаем решение за O(mk), где k -- битовая длина числа.

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

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

Как решать хард див2? Просто никто не решил.