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

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

Предлагаю здесь обсудить задачи прошедшего Гран-При.

Интересно узнать решение задачи K.

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

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

Ссылку на Гран-При в студию.

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

K

Напишем префикс суммы. Пусть мы остановились в местах с префикс-суммами a_1, .. a_k, тогда надо посчитать |a2-a1| + |a3-a2| + ..., ну а минимум этого достигается при монотонном проходе по префикс сумма, что-то типа a_(k + i +/-1) — a_(i) в посорченном массиве.

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

К: заменяем массив на префикс-суммы, дальше у нас есть просто граф с n вершинами, пройти по ребру (i, j) стоит |a[i] - a[j]|, нужно найти самый дешевый путь длины k - 1. Сортим вершины по a[i] и перебираем, какой подотрезок возьмем в качестве пути.

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

Вопрос днища: как решается A, D и H?

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

    D: Чтобы понимать в какую часть мы попадаем на i-ом разделении нужно смотреть i-ый слева бит числа k - 1. При этом последние примерно 60 битов проверяем ручками, а среди первых n - 60 — все биты 0, а значит [(n — 60 + 1)/2] раз добавится к A, и [(n — 60)/2] к B.

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

    H: Общий случай: пусть компания получила p%, тогда 2p% = (после сокращения) поставлено на проигравших и на победителей. У нас ограничения только сверху, поэтому можно считать, что всего ставок y, теперь если y - x > k или k·(n - 1) < x, то все плохо, иначе все хорошо распределяется.

    Осталось понять, что 50% получить невозможно, а 100% соответствует нашему решению для 50% — 0 поставлено на победителя.

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

      А что здесь является y?

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

      Скорее более 49 и менее 100 не можем получить.

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

        Для >50 автоматически получится ( если проверку y - x >  = 0 сделать), так что более менее без разницы

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

    А: сначала решим такую подзадачу: для числа n посчитать f(n) — число способов разбить на 3 неупорядоченных слагаемых. Это . Первое слагаемое получено по формуле включения-исключения и включает варианты, когда все 3 числа различны, второе слагаемое — когда среди трех есть совпадающие.

    Дальше, учитывая, что f(n) не убывает, используем бинарный поиск для нахождения обеих границ. Ответ — некоторый подотрезок натурального ряда.

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

расскажите E, K и J

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

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

    Теперь решение: сперва динама dp[man][pos] сколько с этого момента единиц у человека. Потом выбираем k лучших по dp[man][0] и на каждом шаге проверяем, что в команде все с dp[man][pos] > 0, выкидываем худшего на данным момент и выбираем лучшего из тех, кто не в команде.

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

      Ох чёрт, а я поток написал зачем-то.

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

        А какой там поток?

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

          [количество раундов слоёв], для каждого слоя:

          [2 * количество чуваков] вершин + 2 вершинки для замены.

          2 чтобы ограничение на вершину было, а не на ребро, стандарт короче.

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

          Ну и ищем поток величины ровно k.

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

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

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

    E: Вероятность сменить позицию у встречных людей с L->R или с R->L это . Дальше вроде понятно все. Считаем вероятность нахождения слева и справа для нас и к матожиданию в силу линейности прибавляем вероятности столкновения.

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

      научите решать тервер

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

        Да ладно, зачем вам тервер. Всё же без него решается, смотрите:

        Первые вероятости считаем просто возведением матрички в степень, все умеют, практикуют.

        Затем нужно мат. ожидание посчитать. Тут несколько сложнее. Напишем очевидную динамику: d[i][j][side] -- вероятность после i встреч сменить стороны j раз и оказаться на стороне side. Правда в ней O(N^2) состояний, но это не беда, первое нам не нужно, храним два слоя.

        Осталось со временем разобраться, ведь тоже квадрат же.

        Но и тут можно не думать: интиутивно понятно, что интересных состояний с d[j][side] > eps (1e-18 в моём случае) будет не так уж и много, наверно.

        Пишем, проверяем, ага, ~1000, сдаём за 0.95 с плюса при TL'е в секунду.

        Исходник: http://pastie.org/9095343

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

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

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

          Раз матожидание линейно, то для каждого возможного перехода на другую сторону можно отдельно посчитать вероятность, что он произойдет, а потом просуммировать их. А именно, посчитаем динамику dp[i][side] — вероятность оказаться на стороне side после i первых встреч. Теперь зафиксируем i встреч, которые уже произошли, side — сторону, на которой мы оказались. Вероятность того, что в таком состоянии случится переход на другую сторону, равна dp[i][side] * (вероятность того, что i-ый человек будет на стороне side при встрече). Просуммируем все такие значения — профит.

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

what was the 9th test in h problem?

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

Как решать B?

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

    Например так.

    Сначала наивное решение. Построим 3 бора, в каждом боре в вершине сохраним сет номеров строк. Тогда каждый запрос характеризуется тройкой чисел — номерами вершин в 3 борах. Ответ — это размер пересечения трех сетов.

    Теперь корневая оптимизация. Для каждой вершины бора, если размер сета больше sqrt(N), то заменим его на битсет. То есть вершина бора у нас будет примерно такой:

    struct Node {
       set <int> s;
       bitset <N> * bs;
    };
    

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

    Теперь при ответе на запрос если у нас во всех 3 вершинах сеты, то просто используем set_intersection(), если все битсеты — то используем побитовый and битсетов и используем bs->count(), а если есть и сеты, и битсеты, то пересекаем сеты, а потом проходимся по сету и проверяем, есть ли элемент в битсете.

    Вроде это работает за O(Nsqrt(N)) — на онсайте за секунду зашло.

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

      The translation says "construct 3 boron" actually what did you mean? suffix array/automaton or something else? a bit translation would be great. or may be source code (its universal language :))?

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

      А почему это не n ^ 2 / 64? Если так, то корневая не нужна, с нехваткой памяти можно бороться более простым способом. Просто разобьем все id на группы по k штук, для каждой группы будем решать отдельно. Использовать будем только битсеты. В каждом битсете, лежащем в вершине бора, будет использоваться k / 64 памяти, что в сумме мало. Обработаем все запросы для данной группы за q * k / 64. В сумме получим n * q / 64. Нам пришлось немного попихать в дорешку, но все-таки зашло.

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

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

    Для каждого из 3 полей сохраним все возможные его строчки и запросы в боре. Занумеруем вершины каждого бора в порядке обхода dfs'а. Теперь каждый ID туриста характеризуется 3 числами — позициями соответствующих вершин в порядке обхода, назовем их x, y, z, тогда ID будет точкой в трехмерном пространстве. Запрос так же характеризуется 3 вершинами, и ответом на запрос является число таких ID, что соответствующие ему вершины лежат в 3 поддеревьях вершин запроса. Так как мы пронумеровали все вершины бора в порядке обхода, то в одном поддереве будут лежать вершины с последовательными номерами от L до R. Зная такие границы для каждой вершины, можно ввести ограничения на каждую координату искомых точек и свести запрос к задаче нахождения количества точек внутри параллелепипеда.

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

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

      Мы так же делали, но раз уж оффлайн, можно вместо декартовых использовать фенвика.

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

        Since, N ~ 1e5, how will you do 2d-range-query (for sweeping one dimension will be reduced) in Fenwick tree? Don't you need 2D BIT?

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

          You can use 2-D Fenwick tree, which is very easy to implement. Just compress the first coordinate and for each valid first coordinate maintain a Fenwick tree by the compressed second coordinate in a separate vector.

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

Понравелось задание "H", но если в условиях было бы 0 < A[i] <= K, стало бы интересней.

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

    А чем интересней? Прибавим ко всем единичку, а потом тоже самое.

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

      Мне показалось, что надо считать хватит ли этих единичек, и для того подберать максимальные числа, непревышающие k.

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

        В любом случае давайте ко всем прибавим единичку и теперь мы решаем ту же задачу только с K на единицу меньше.

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

          Был неправ, согласен. Как говорят — дошло.

»
10 лет назад, # |
Rev. 2   Проголосовать: нравится +22 Проголосовать: не нравится
  • A: We found the formula to be: (n^2 + 6)/12, but we don't know how, how did others solve it?
  • D: You can solve it by converting K to binary. And check the bits
  • E: You just need to know what is the probability one would change side in T seconds. It is: sum ncr(n, 2i) * p^2i * q^(n — 2i) which has a closed form. Then somewhat easy, you may O(n) dp or just looping :)
  • G: We did not get time to solve it. But it seems you need to have 5 arrays which will say for each position where is the first 1~5 in certain direction. And then simulate
  • H: Loop over the # of bet for winning team. You will get the sum of bets for loosing teams. Now distribute them. A special check is for P = 100. and 100 > P >= 50 is impossible.
  • J: For each question have a bitmask for the stundets who can answer it correctly, say this is: possible[0][i] for ith question. Now, possible[j][i] = possible[j — 1][i] & possible[j — 1][i + 1] and in this way build possible[0..k-1]. Now its turn to go down. For possible[k — 1] make solution[k — 1] which will contain 1 participant which is in corresponding possible[k — 1]. While going down, solution[j][i] = solution[j + 1][i] | solution[j + 1][i — 1]. And if it is not of size k — j add additional participants from participant list. So you get your answer in solution[0] array
  • K: say qi is the dist to i'th city. Take cumulative sum Sq. So going from i to j means: |Sqi — Sqj|. So sort all Sq's and try to take consecutive k Sq's. Check which one is minimum.
  • I am not sure:
  • C: for each side, extend its neighboring side outwards to get a triangle / parallel line. Now you know what should be the additional area of the extended triangle. Now since you know the area you will get a line where the peak have to of the extra point. see if there is any lattice point on that line and between the feasible boundary we defined earlier.
»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

if P==100

1

0 0 0 0 ... 0 is true?

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

ok,but what is answer for P=100?

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

Видимо, сдвоенный опенкап — не очень хорошая идея.
Когда победитель определяется за 2 тура до конца, следующие 3 места за тур до конца, это не есть хорошо.
Вот даже из пяти участников Petr Team ни у кого не нашлось мотивации написать сегодня последний тур :(.

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

    Участников Petr team слегка раскидало по миру просто

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

      Не надо, это не проблема в наше время. Есть возможность и досрочно написать.
      Уверен, что, если бы вы имели шансы на 1-е место, то точно нашли бы возможность.
      Я это не вас критикую, а формулу соревнования. Если бы было 7+7, то результат был бы оба раза не ясен до разморозки последнего тура.

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

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

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

          В мае сессия у студентов, туда тоже не особо хочется этапы назначать

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

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

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

              Просто Кубок как-то занимает почти весь день — пока доедешь до сектора, пока напишешь, пока пообедаешь после и вернёшься из сектора...

              Поэтому писать каждое воскресенье довольно напряжно.

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

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

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

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

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

                  ------------------------------- Странная идея, по-моему.
                  Я изначально написал о потере спортивного интереса в конце соревнования. Понятно, что 8 из 13 уж никак его не добавит. Может только в борьбе за самый топ, но, например, если речь идет о выходе в онсайт, то это правило будет крайне странным.

                  Вообще, предстаьте себе Формулу-1 и Феттеля, который последние этапы едет на Жигулях, помахивая рукой зрителям :)

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

                  Ну здесь конфликтуют несколько интересов: 1) участники, у которых много свободного времени, хотят как можно больше этапов. 2) участники, у которых мало свободного времени (например Petr team), хотят, чтобы у них был шанс побороться за победу, участвуя примерно раз в 3 недели. 3) философски хочется, чтобы была интрига до последнего этапа.

                  Я не вижу решения, которое удовлетворяет свойствам 1-3, поэтому предлагаю то, которое удовлетворяет 1 и 2. Что произойдёт со свойством 3 — сказать сложно. Может быть, интриги в конце как раз будет больше, потому что мы сможем пропускать этапы по ходу, отдохнём, а в конце как раз спортивный азарт возьмёт верх.

                  Два сезона 7+7 удовлетворяет свойству 1, но не удовлетворяет 2 (потому что этапов и зачетных этапов по-прежнему много) и, как следствие, свойству 3 (потому что у команд, у которых мало свободного времени, меньше мотивации бороться, когда это требует участия каждую неделю).

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

C, F, I?

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

    I: Drawing some cases you can notice that no car need to go back ever because of two-lane first and last segments. The most effective way to avoid accident is always such: one of the car need to stop in the last but one (in its direction) X-coordinate of two-lane segment before the accident place, after stop it waits a moment when another car "touch" it (look at first case on the second picture in statement) and starts moving. Also you can notice that R doesn't influence to anything, so you can ignore it. So, we have some states (maybe more — depends on implementation): 1) first car is in A-point and second car somewhere at the road, 2) second car is in B-point and first car somwhere at the road. Moving from one state to another is simple — O(log(L)). Number of states is not big and you can easily find (using simple modelling) result for period from zero-time till the time some state firstly occured. When some state occured for the second time — it's a cycle. You just need to find number of cycle repeat and to do a modelling for remaing time. Complexity: O(cycle_length * log(L)).