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

Автор try_kuhn, 3 года назад, По-русски

Всем доброго времени суток! На этот пост меня вдохновил Wind_Eagle своим постом.

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

Для начала подведу итоги челленджа. Он оказался скорее неуспешным, чем успешным. Единственное, что я получил от него — опыт, который будет полезен в будущем. Итак, итоги:

  • Взять диплом на республике. Не выполнил, остался без диплома. Нарешал очень плохо, наконец понял, что главная проблема не столько даже лежит в программировании, сколько в психологии. Заметил очень нехорошую особенность: пришёл как на первый, так и на второй тур, все 5 часов не мог сосредоточиться, чего-то боялся (сам не знаю, чего). Из-за этого я фактически не думал, а скорее просто выписывал на листочке что-то и пытался просто реализовать то, что всё-таки смог заметить. Получил 302.65 баллов, когда на диплом надо было 385. Эта проблема была всегда у меня, но я как-то не обращал на неё внимания, просто потому что считал её несерьёзной. Также ещё одна из возможных причин кроется в названии поста, далее поясню, что я имею под этим ввиду.

  • Выиграть олимпиаду первого уровня. Ещё нет результатов по олимпиаде ИТМО, но это последний шанс. Ближе всего я был к диплому на высшей пробе (опять же по глупости получил по B задаче 19 вместо 100, потому что использовал ДО на максимум вместо префиксных максимумов) и Технокубке, на котором просто не успел заслать D задачу.

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


Теперь к основной части. Так почему же вам скорее не помогут сложные темы?

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

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

Теперь перейдём к изучению тем. Для школьных олимпиад (по карйней мере в Беларуси) не требуется знания каких-то сложных тем, как потоки, декартово дерево, Segment Tree Beats (Анимешное ДО). Ошибкой стало их изучение, тем более за полтора месяца до олимпиады. Далее привожу темы, которых, по моему мнению, достаточно, чтобы взять призёра олимпиады первого уровня перечня РСОШ или какой-то олимпиады уровня республиканской в Беларуси:

  • первое и главное: умение решать "в лоб"

  • умение писать задачи на реализацию (все таски которые вы знаете как решать, но вам лень реализовывать)

  • бинарный поиск, в том числе по ответу

  • тернарный поиск

  • префиксные суммы / минимумы / максимумы

  • встроенные в stl структуры данных: map / set / multiset

  • встроенные в g++ структуры данных: ordered set / ordered multiset, их особенности и баги

  • простая теория чисел (алгоритм Евклида, решение линейных диофантовых уравнений, операции по модулю, решето Эратосфена, в том числе умение находить простые делители для всех чисел до $$$n$$$ за $$$O(n \log \log{n})$$$)

  • простая комбинаторика: сочетания, перестановки, "количество способов"

  • методы решения задачи в оффлайн: алгоритм Мо, сканирующая прямая

  • оптимизации при помощи bitset

  • дерево отрезков, в том числе с отложенными операциями и на указателях

  • разреженная таблица

  • система непересекающихся множеств

  • знание стандартных жадных алгоритмов, умение "поподбирать компаратор"

  • <метод отжига для решения задач с открытыми тестами>

  • основы теории игр

  • знание графов/деревьев и основных алгоритмов по ним: BFS, DFS, Дейкстра, алгоритм Прима, LCA

  • строки: полиномиальное хеширование, <префикс-функция, Манакер>

  • ну и конечно, знание и понимание стандартных приёмов динамического программирования

  • <очередь с поддержкой минимума>

<> я пометил опциональность

UPD: По поводу психологии на туре очень интересно было почитать статью и посмотреть лекцию тут.

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

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

А где задачи на эти темы решать?

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

    Если вы хотите чего-то стандартного, отработки методов, то вам в секцию Edu codeforces / на usaco.guide

    Если же вы хотите тренировать идейность, то решайте конструктив.

    Если у вас проблема с медленным написанием кода, то вам конечно же нужна реализация.

    Хоть поиск по тегам на codeforces не очень точный, но я часто им пользуюсь чтобы порешать что-то определённое.

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

Осуждаю хеши, обычно загонять их значительно сложнее и дольше, чем те же самые караси/z функции и тд, а также НУЖЕН фенвик, ибо им в половине случаев можно заменить ДО/ДД и это будет писаться раз в 10 быстрее, а еще и будет работать раза в 2 быстрее.

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

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

    По поводу Фенвика очень часто слышу. Но лично я предпочитаю писать ДО снизу. Кода не сильно больше, производительность такая же, но зато более гибкая структура, чем Фенвик. Может есть какие-то ещё плюсы, но я про них не слышал. Если реально есть ещё что-то, буду рад прочитать коммент с пояснением

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

      Ну оно пишется в 2 строчки, в нем невозможно набагать, его можно юзать вместо merge sort tree (а это та структурка, что очень часто вылезает), ибо там можно хранить другой массив/ДО/Фенвик, и это -1 ДО, что очень хорошо

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

        "Невозможно набагать" — я 20м дебажил фенвика потому что не мог вспомнить формулу

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

          Ну это происходит ровно один раз в жизни)

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

            Ну если всеукр будет то возможно произойдет и 2ой)

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

          Надо писать 1-indexed фенвика, тогда в обоих функциях будет одна и та же формула i += / -= lowbit(i), слово "lowbit" уж как-нибудь да запомнишь.

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

      Иногда полезнее писать как раз Фенвик, так как он пишется в несчастные две строчки, тем самым сокращая время написания кода и колво ошибок в коде.

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

Да, психология на туре очень важна. Реклама: моя лекция восьмилетней давности (когда ещё не было обратной связи на турах или хорошей камеры с микрофоном у меня) и пост от KAP (может быть актуальнее для современных реалий).

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

    Спасибо вам огромное! Возможно это как раз то, что может помочь. Если вы не возражаете, я дополню блог этими ссылками

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

не концентрируйтесь на решении слишком сложных задач, это вам скорее помешает, чем поможет

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

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

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

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

Я тоже учил всякие Segment Tree, Meet in the Middle, SOS DP, Sparse Table, но это всё редко помогает решить Div2C/D, хотя недавно написал спарсу с бинариком.

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

P.S. я бы писал Крускала вместо Прима, если бы хоть раз его увидел в задаче. КЕК

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

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

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

Увидел эту статью когда готовился к респе. По итогу взял первую похоронку (×﹏×)