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

Автор aropan, 12 лет назад, По-русски
Можно было перебирать каждую позицию и проверять подходит ли она под условия a ≤  i - 1 и n - i ≤ b (для i от 1 до n). Первое условие можно преобразовать в a + 1 ≤ i, а условие n - i ≤ b в n - b ≤ i, тогда общее условие можно записать max(a + 1, n - b) ≤ i и тогда наш ответ можно вычислить по формуле n - max(a + 1, n - b) + 1.
Авторское решение

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

Все позиции кроме первой и тех, чей номер простое число большее |s| / 2 должны иметь одинаковый символ. Оставшиеся же позиции могут быть любыми. Как это показать: рассмотрим позиции, которые должны совпадать для p = 2 это 2,4,6,8... теперь возьмем позицию с номером x ≤ |s| / 2, эта позиция должна иметь тот же символ что и на позиции 2, так как символ x должен быть равен символу на позиции 2 * x, который в свою очередь равен символу на позиции 2. Теперь рассмотрим позиции, чей номер больше чем |s| / 2. Если эта позиция имеет номер не простое число значит есть простое число p на которое делится номер нашей позиции и p ≤ |s| / 2. Символ в позиции p равен символу в позиции 2, так как p ≤ |s| / 2 значит и символ в нашей позиции также соответствует символу в позиции 2. Оставшиеся же позиции не объединяются ни с какими другими позициями поэтому символ который стоит в них ни на что не влияет.
Найдем символ который встречается максимальное количество раз и пробуем этот символ расставить на позиции символы в которых должны быть равны. Если этого символа на все позиции не хватает тогда ответ "NO", иначе оставшиеся символы расставляем как угодно на остальные позиции.
Авторское решение

Повернем поле на 45o преобразовав координаты клетки (x, y) в (x + y, x - y). Тогда клетка (x, y) будет плохой, если будет выполняться одно из условий x ≡ 0 (mod 2a) или y ≡ 0 (mod 2b). Т.е. неплохие клетки будут разбиты на сектора вертикальными и горизонтальными прямыми. Для каждого сектора можно определить его координаты парой чисел, первое число которое будет увеличиваться при переходе в соседний правый сектор, а второе число пары будет увеличиваться при переходе в соседний верхний сектор. Из сектора с координатами (x, y) можно перейти в любой соседний по стороне сектор, посетив минимум 1 плохую клетку, т.е. в (x - 1, y), (x + 1, y), (x, y - 1) и (x, y + 1). Так как числа 2a и 2b имеют одинаковую четность, то из сектора (x, y) также можно перейти в сектор по диагонали, посетив также 1 плохую клетку, т.е. в (x - 1, y + 1), (x + 1, y - 1), (x - 1, y - 1) и (x + 1, y + 1). Тогда получается что минимальное количество плохие клеток, которые должны быть посещены по пути из сектора (x1, y1) в сектор (x2, y2) будет равно max(|x1 - x2|, |y1 - y2|).
Преобразуем координаты начальной и конечной клеток по вышеописанному правилу. Потом найдем в каких секторах находятся наши клетки и вычислим ответ по вышеописанной формуле.
Авторское решение

Для начало сведем задачу к одномерной матрицы. Рассмотрим монотонный путь (1, 1), (1, 2), ..., (1, m - 1), (1, m), (2, m), ..., (n - 1, m), (n, m) по которому получается правильная скобочная последовательность. Теперь в этом пути можно заменить клетку (1, m) на (2, m - 1) и по прежнему путь будет монотонным и будет образовывать правильную скобочную последовательность. Значит в клетках (1, m) и (2, m - 1) стоит скобка одного типа. Продолжая так дальше ( например заменить (1, m - 1) на (2, m - 2) или (2, m) на (3, m - 1)) можно увидеть, что в клетках (i, j) и (i - 1, j + 1) стоит скобка одного типа. Тогда у нас получается не двумерный массив n × m, а одномерный размером n + m - 1. Для каждой позиции можно определить какой у неё наибольший приоритет, т.е. для клетки i (1 ≤ i ≤ n + m - 1) приоритет будет равен минимальному значению px, y где 1 ≤ x ≤ n, 1 ≤ y ≤ m и x + y - 1 = i.
Теперь перебираем позиции, начиная с наиболее приоритетных. Ставим в эту позицию скобку "(" и считаем сколькими способами можно доставить оставшиеся скобки, чтобы получалась правильная скобочная последовательность. Если количество способов не меньше k, тогда оставляем в этой позиции скобку "(", иначе уменьшаем k на количество способов и ставим в эту позицию скобку ")". И так проходим по всем позициям. Для того чтобы посчитать количество способов каждый раз просчитывается динамика по двум параметрам fi, j, где i количество обработанных позиций, а j количество открытых скобок. Если на позиции i + 1 скобка ещё не определена тогда можно перейти в fi + 1, j + 1 или  fi + 1, j - 1, если же определена тогда только в fi + 1, j + 1 или только fi + 1, j - 1 в зависимости открывающаяся или закрывающаяся скобка соответственно.
Авторское решение

Отсортируем все суффиксы строки (обозначим как массив строк ci). Тогда ответ на задачу будет количество таких 1 ≤ i ≤ j ≤ |s| и 1 ≤ k, что префиксы длины k у всех строк сi..j равны. Варианты когда i = j и 1 ≤ k ≤ |ci| можно просчитать сразу, это равно количеству подстрок в строке, т.е. |s| * (|s| + 1) / 2. Теперь посчитаем LCP (самый длинный общий префикс) для соседних суффиксов, т.е. ai = LCP(ci, ci + 1) для 1 ≤ i < |s|. Тогда теперь надо посчитать количество таких 1 ≤ i ≤ j < |s| и 1 ≤ k, что k ≤ min(ai..j). Эта задача на подсчет количества прямоугольников, если есть ограничение на высоту в каждом столбце, т.е. ai максимальная высота прямоугольника в столбце i. Решается при помощи стека или списка.
Авторское решение

Рассмотрим чему равно матожидание для фиксированного входа и выхода. Понятно что из входа в выход будет существовать всего лишь один путь, который в любом случае будет пройден. Также ещё можно пойти в неправильном направлении. Рассмотри случай когда выбрана вершина, из которой есть k ложных путей и один верный (он есть всегда). Тогда перед тем как пойти в верном направлении возможно 2k равновероятных способов обхода ложных путей. Каждый ложный путь входить в 2k - 1 способов и увеличивает количество ходов на 2 ×  < размер ложного поддерева >  т.е. матожидание от ложного пути увеличиться на 2 ×  < размер ложного поддерева >  × 2k - 1 / 2k =  < размер ложного поддерева > . Тогда матожидание в вершине равно сумме  < размеров ложных поддеревьев >  + 1 (это ход в верном направлении) +  матожидание от вершины в которую пойдем, идя в верном направлении. В итоге получается, что матожидание равно количеству достижимых ребер из входа, не проходя через выход.
Запустим обход в глубину и каждую вершину рассматривать как вершину выхода. Тогда если в каком-то поддереве определяется вход, то матожидание равно размеру этого поддерева. Просчитываем сколько в каждом поддереве будет количество входов и вычисляем количество ходов, если выход находится в текущей вершине. Также надо не забыть просчитать случаи когда текущая вершина является выходом, а вход расположен выше по обходу дерева.
Авторское решение
Разбор задач Codeforces Beta Round 92 (Div. 1 Only)
Разбор задач Codeforces Beta Round 92 (Div. 2 Only)
  • Проголосовать: нравится
  • +13
  • Проголосовать: не нравится

12 лет назад, # |
  Проголосовать: нравится +2 Проголосовать: не нравится
Пожалуйста, объясните словами чуть более подробно смысл рекуррентности (динамики) в задаче C div 1 (Скобочки). Для меня уже во время раунда было очевидным всё, что подробно объяснено в разборе, но рекуррентность что-то не получается понять даже сейчас, видя готовый код...
  • 12 лет назад, # ^ |
    Rev. 5   Проголосовать: нравится +6 Проголосовать: не нравится

    Не стал разбираться именно с авторским решением.

    Рассмотрим подзадачу:

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

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

    D(pos, balance) // количество способов расставить скобочки в позиции pos, pos + 1, pos + 2,..., s.size() - 1

    string s;

    int D(int pos, int balance)
    {
        if (pos == s.size())
        {
            if (balance == 0)
                return 1;
            else
                return 0;
        }
        if (s[pos] == '*') // в шаблоне на позиции pos ничего не стоит
        {
            int res = D(pos + 1, balance + 1); // ставим (
            if (balance > 0)
                res += D(pos + 1, balance - 1); // если можем ставим )
            return res;
        }
        else
        {
            if (s[pos] == '(') // в шаблоне уже стоит (
                return D(pos + 1, balance + 1);
            if (s[pos] == ')' && balance > 0) // в шаблоне уже стоит )
                return D(pos + 1, balance - 1);
            return 0;
        }
    }
    

      

    чтобы посчитать для всей строки следует вызвать D(0, 0)  

    • 12 лет назад, # ^ |
        Проголосовать: нравится +2 Проголосовать: не нравится
      Спасибо. Всё действительно просто, надо было только не стараться править обычный вывод формулы чисел Каталана, а взглянуть чуть по-другому...

      На всякий случай уточню для менее опытных участников: имеется в виду, что в вышеприведённый код надо добавить обычный приём рекурсии С ЗАПОМИНАНИЕМ.
12 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Please post a english editorial
12 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Спасибо, действительно все понятно)
Единственное что, задача А первого дивизиона имеет более изящное решение, а именно min(b+1, n-a), ну, это на любителя, так сказать.
12 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Спасибо, действительно хороший разбор!
Но в авторском решении по задаче D(div 1) немного не понятен один кусок кода. Не могли бы вы объяснить, для чего он предназначен? Спасибо.
    n = 0;
    h[n] = -1;
    w[n] = 0;
    f[n] = 0;
    n++;

    for (int i = 0; i < k; i++)
    {
        int l = 1;
        while (h[n - 1] >= a[i]) l += w[--n];

        w[n] = l;
        h[n] = a[i];
        f[n] = f[n - 1] + (long long)l * a[i];
        n++;

        ans += f[n - 1];
    }
  • 12 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    "...подсчет количества прямоугольников, если есть ограничение на высоту в каждом столбце, т.е. ai максимальная высота прямоугольника в столбце i..." через стек. Будем переходить от столбца к столбцу, поддерживая стек блоков (wi - высота, hi - ширина блока и fi - площадь всех блоков в стеке до i-ого включительно). Высота будет возрастать, так как если очередная высота блока меньше предыдущего, то блоки можно объединить в один, обрезав предыдущий по высоте. Тогда после добавления любая клетка одного из наших блоков может быть левым верхним углом прямоугольника (правая же сторона будет заканчиваться в текущем столбце).
    • 12 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Извиняюсь, но никак не могу понять, к какой задаче именно вы сводите. К задачи подсчета количества прямоугольников, не могли бы вы дать полное условие именно этой подзадачи для полной ясности. Спасибо
      • 12 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Предположим что в i-от столбце есть в высоту ai клеток. Требуется посчитать количество прямоугольников образованных на этих клетках таких, что нижняя часть прямоугольника примыкает к нижней границе.
12 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Could someone help me with this:  in problem D, how to compute LCP(ci, ci + 1) quickly?  Some solutions use a binary search for that part, I don't understand why it works that way.
  • 12 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится
    I used the suffix array.
  • 9 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    I used Suffix Automaton to solve this problem. & I think Suffix Automaton is very much easier than implementing Suffix array here.

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

      Can you please tell what is the intuition behind suffix automaton & how it will be used to solve D here ? Any help will be appreciated.

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

I've solved the A with min(n — a, b + 1)

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

    sir can you give me the reason please

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

      Maths are not my strongest point, so I can't provide a mathematical explanation.

      My logic is (was):

      If there are at least A people in front of me, I am sure that I would never be on any of those positions. So, I'll be in some position between the last one of them and the end of the queue. This leaves me in a range of N — A positions, at most.

      If I have, at most, B people between me and the end of the queue, I'll be in a position in the range b — 1 (just ahead of the first person of the B group) to the end of the queue. This is a range of B + 1 positions, at most (as from the statement "not more than B", means that may be less than that quantity).

      So, if we put together those two requirements ("N — A positions, at most") and ("B + 1 positions, at most"), we have to get the lowest of the two values (based on the "at most" part on both of them. This means taking the min function of both.

      The result comes from min(n — a, b + 1)

      Hope my explanation is clean enough and it helps you understand my approach.

      Happy coding!

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

У МЕНЯ ЕСТЬ ВОПРОС!!! В первой задаче сказано что перед Петей не менее а человек, а после него не более b человек, а в 3-ем тесте дано n=5, a=4, b=0, т.е. перед ним не менее 4 человек, а после него не более 0. Значит если перед ним не менее 4 человек, а после него не более 0 и всего 5 человек в шеренге, то он занимает 5 позицию, а 3-й тест выдает 1-ю позицию. Если я ошибаюсь, то объясните пожалуйста. P.S. Я решил формулой max(a+1,n-b);

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

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

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

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

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

Can we solve Div2-B with faster algorithm ?

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

Did not quite understand how "max(a + 1, n - b) ≤ i and then our answer can be calculated by the formula n - max(a + 1, n - b) + 1." takes place. Would anyone like to explain the +1 part?

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

In A the problem text says that "...and no more than b people standing behind him."

So, there are 0 up to b people behind him. Not more, but maybe zero. If it is zero people behind him, then literaly no position get occupied by them. So b can and must be simply ignored.

Is it a translation error?

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

    I see you have accepted the task. Still have a question?

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

      I think I understood.

      The sentence "...and no more than b people standing behind him." implies that at least a given numer of people are standing in front of him. So b cannot be ignored.

      Since this is the key observation it would have helped to state that in the tutorial text. Thanks anyway.

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

i am getting Unable to parse markup error ? wtf ?

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

Can someone explain the solution of problem D squares in more details ? I can't figure out the rotation and the sectors in the editorial.

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

Pretty old problem but I solved it recently.

In A, we can just find the min of n-a and b+1, right? aropan Here is the submission for the same.Solution

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

    How does it make sense? Care to elaborate?

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

      According to the problem statement, there are at least (a) people in front of him and at most (b) people behind him.

      Note: It's possible to have no people behind him at all, in that situation the position he can occupy is equal to (n-a) This works fine if (b) is exactly before (a) Formally (a+b = n)

      But what if that is not the case (a+b!=n) :

      According to the statement, His pos should be exactly after b, as people in front of him can be more than (a) which is not the case with b (people behind him must equal to (b) or less) so you can use min(n-a, b+1)