Блог пользователя danilka.pro

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

441A - Валера и антиквариат

Автор задачи gridnevvvit

Нужно реализовать то, что записано в условии. Например, это можно сделать так: посчитаем qi — минимальная цена товара у продавца i Тогда если qi < v, то мы можем заключить сделку с продавцом i. Иначе не сможем.

Авторское решение: 6850474

441B - Валера и фрукты

Автор задачи gridnevvvit

Будем последовательно перебирать дни от 1 до 3001. Пусть текущий день это день i. Кроме того, дополнительно будем поддерживать величину cur --- количество фруктов, которые мы не успели собрать в предыдущие дни. Предположим, что в день и созреет now фруктов. Если now + cur ≤ v, то нужно добавить к ответу now + cur и обновить значение cur (cur = 0). Иначе к ответу нужно прибавить величину v, а величину cur обновить следующим образом. Пусть tv = max(v - cur, 0). Тогда cur будет равен величине cur = now - tv. Иначе говоря, сначала мы пытаемся собрать те фрукты, которые завтра уже испортятся.

Кроме того, можно решить задачу и за . Однако, этого не требовалось.

Авторское решение: 6850502

Бонус. Предположим, что фрукты можно собирать в дни ai, ai + 1, ..., ai + Ti, где Ti — некоторое заданное число для каждого дерева. Как решить оптимально такую задачу? Да, еще. Кроме того, для каждого дня заданное свое значение v (производительность труда в каждый день).

441C - Валера и трубы

Автор задачи gridnevvvit

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

  1. Пусть сначала мы стоим клетке (1, 1). Слева направо дойдем до самой правой клетки поля в этой строке, до клетки (1, m).
  2. Перейдем на следующую строку, в ячейку (2, m). Справа налево дойдем до самой левой клетки поля в этой строке, до клетки (2, 1).
  3. Перейдем на следующую строку. Повторим действия из пунктов 1. и 2. до тех пор, пока не посетим все клетки.

После того, как мы построили такой обход, получить ответ не трудно: достаточно первые (k - 1) трубу сформировать из 2 ячеек, а последнюю трубу из оставшихся.

Авторское решение: 6850508

441D - Валера и обмены

Aвтор задачи danilka.pro

В данной задаче удобно представить перестановку в виде ориентированного графа c n вершинами, а из каждой вершины i проведено единственное ребро в вершину p[i]. Очевидно, что этот граф полностью состоит из простых циклов.

Если провести операцию обмена (i, j), то ребра и станут ребрами и соответственно. Тогда, если i и j находятся в одном цикле, то этот цикл разорвется:

а если в разных, то циклы, в которых они содержатся, соединятся в один:

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

На основании всего вышеизложенного, чтобы получить перестановку q из перестановки p, нужно увеличить (или уменьшить) число циклов в перестановке p до n - m. Пусть с — число циклов в перестановке p. Тогда k всегда равно |(n - m) - c|.

Для выполнения условия лексикографической минимальности, рассмотрим три случая:

1) n - m < c

Очевидно, что в этом случае выгоднее всего уменьшать число циклов, соединяя их с циклом, содержащим вершину 1. Таким образом, в этом случае любой обмен имеет вид (1, v), где v > 1. Поскольку вершина каждого последующего цикла больше предыдущей, данный случай решается за O(n).

2) n - m > c

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

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

3) n - m = с

Так как в этом случае k = 0, никаких обменов делать не нужно.

Крайне рекомендуется ознакомиться с авторским решением: 6850515

441E - Валера и число

Автор задачи gridnevvvit

Решать задачу будем следующим образом: будем считать динамическое программирование d[i][mask][last][cnt] — вероятность получить через i шагов такое число v, что его последние 8 бит равны маске mask, 9-ый бит равен значению last, а cnt — это количество подряд идущих бит (начиная с 9-го бита) которые равны по величине значению last.

Хорошо, а почему мы отбросили остальные биты? Понятно, что используя операцию  +  = 1 мы сможем изменить только первый нулевой бит, индекс которого  ≥ 9.

Переходы достаточно очевидны: либо мы прибавим единицу, либо  *  = 2 (Подробнее их можно изучить в моем решении). Возможно, следует задать вопрос такой. Например, мы имеем число в двоичном представлении x = 1011111111.

И в текущий момент, мы делаем  +  = 1. Согласно тому, что я написал выше, мы должны перейти в состояние d[1][0][1][2], однако мы не сможем этого сделать, поскольку у нас нет никакой информации о 1 в 10-ой позиции. Однако, поскольку мы не сможем больше изменить никакой бит с индексом  >  = 9 (так как mask = 0) мы сделаем переход в состояние d[1][0][1][1].

Авторское решение: 6850523

Бонус. Предположим, что мы имеем немного другой псевдокод.

// input x, k, p
 
for(i = 0; i < k; i += 1) {
   if (x четное) {
     rnd = случайное число на отрезке [1, 100]
     if (rnd <= p)
       x *= 2;
     else
       x += 1;
   } else {
      x *= 2;
   }
}
 
s = 0;
 
while (x четное) {
  x /= 2;
  s += 1;
}
 

Как и прежде, нужно найти математическое ожидание s.

Насколько эффективно вы можете решать такую задачу? Можете ли вы доказать свое решение?

Разбор задач Codeforces Round 252 (Div. 2)
  • Проголосовать: нравится
  • +50
  • Проголосовать: не нравится

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

Бонус задачи B

Заведем массив векторов из пар для каждого дня, в каждой паре будем хранить приоритет и номер дерева с которого можно срывать в этот день. Затем сортим по приоритетам и проходясь по дням считаем ответ. Пусть худший приоритет будет Xi, где Xi — количество дней в которые можно срывать. Тогда приоритет, требующий обслуживания прямо сейчас равен 0.

UPD Точно так же можно было решать и саму задачу B, только в ней было два приоритета — 1 и 0.

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

Умею решать бонус к задаче Е за .

Заметим, что s = numberOfTrailingZeros(x).
На каждой итерации будем хранить вектор вероятностей v = (v0, v1, ...)T, где vi = prob[numberOfTrailingZeros(x) = i]. Изначально vn = 1 и vi = 0i ≠ n, где n = numberOfTrailingZeros(x).
Теперь заметим, что если у нас на какой-нибудь итерации x нечетное, то перейти можем только в состояние с одним не ведущим нулем, в противном случае, пусть m = numberOfTrailingZeros(x), тогда переходы возможны в состояние с нечетным числом с вероятностью и в сосстояние с m + 1 не ведущим нулем с вероятностью . Дальше несложно построить матрицу переходов:


Осталось только возвести M в k-ую степень, домножить на v и посчитать матожидание.

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

    я умею решать гораздо быстрее.

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

      Ну да, матрица лишняя.

      dp[номер текущей итерации][количество не ведущих нулей в бинарном представлении] — состояний, переходы за описаны выше. Итого .

      Но можно ещё быстрее!

      Будем хранить дерево отрезков, которое умеет считать сумму на отрезке, изменять в точке и домнажать числа на отрезке на константу. Пусть m — позиция, начиная с которой в дереве отрезков хранится наша динамика (изначально m = k). Тогда все наши действия эквивалентны следующему коду (код понять легче, чем объяснить словами):

      // input x, k, m
      m = k;
      size = k + numberOfTrailingZeros(x);
      update(m + numberOfTrailingZeros(x), 1);
      
      for (i = 0; i < k; i = i + 1) {
        sum = getSum(m + 1, m + size);
        update(m - 1, sum * (100 - p) / p);
        multiply(m + 1, m + size, p / 100);
        m = m - 1;
      }
      

      То есть мы на каждой итерации наша динамика хранится в отрезке [m, m + size].
      Итоговая сложность .

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

        На самом деле, это не предел. Рассмотрим отдельно два случая, когда p = 0 и когда p = 100. Это достаточно просто, я не буду описывать как это сделать.

        Теперь пусть 0 < p < 100 и pl = (100 - p) / 100. Рассмотрим вероятность нулевого количества бит на i шаге. Пусть эта величина равна x. Тогда на следующем шаге вероятность нуля будет равна f(x) = (1 - x) * pl. Хорошо. Давайте найдем производную (f'(x)) такой функции. Очевидно, она равна f'(x) =  - pl. Значит, для любого x |f'(x)| < 1, значит f(x) сжимающее отображение (понятие из функционального анализа). У сжимающего отображения есть одна неподвижная точка, к которой будет сходится последовательность x, f(x), f(f(x)) и так далее. А поскольку при больших k вероятности получить больше нулей на конце в двоичной записи зависят как раз от вероятности нуля, то искомый ряд вероятностей сойдется к некоторому ряду. На практике же, можно ограничится тем, что k можно ограничить небольшим числом, например значением 1000 (вроде это уже даже многовато).

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

When will the eng for div2 d, e come out?

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

When will english translations be available?

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

In problem E editorial, what is 'v' (mentioned in first line)? I would also like to know how you arrived at the DP state you described. Thanks!

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

    v — is some number, which satisfy this pattern (mask, last, cnt).

    Because number of operation is small ( ≤ 200) then we can understand, that only last 8 can be changed by adding operations (and first zero bit with index  ≥ 9). So, after that we will have such dp states

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

      Can you please give example of how the states are represented by dp[i][mask][last][cnt]?

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

      Sorry,I just press the wrong button.I just want to ask,as there are so many states,will it TLE?Is the transfrom O(1)?

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

How an easy solution for C!!! I wrote a complex code to do this task, and finally it was failed on system test :(
It's not the first time for me doing this mistake, any suggestion? any trick? How can I think about problems in the easier manner?

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

Sorry, but I don't understand well dans' explanation about problem D, why always do we need to increase (or decrease) number of cycles in p to n - m?....... What about if we have only a cycle with length m + 1, could be that q? can anyone explain that?

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

    Because to break a cycle into 1-length cycles with length l you need l - 1 swaps. Then to break all the cycles you need swaps. c is number of cycles in p.

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

Problem D-
how output of
3
2 3 1
0
is
2
1 2 1 3
this will happen with above ans (231) -> (132) -> (312) but final state should be (123)
EDIT: I got it. swap is operated on index. my mistake.

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

I am unable to understand how the graph is used for representing the permutation,can anyone help me??If there exist a only 1 edge from i to p[i], then how cycles are formed??

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

can aNybody plz explAin problem E, this type of problem is completely new for me or link to some tutorial?

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

    Problem E could be solved using dynamic programming method. It is very common, so the better way is to inspect others solutions. Even this task could be solved using DP in different ways. If you are completely new to DP, you can read Wikipedia, inspect posts on Codeforces, or simply use google for it.

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

      Hi guys,

      I've seen others' dp solutions such as 6963686 that have used way easier dp solutions than the one in the analysis (this solution uses only 2 dimensions for the dp). Does anyone know an explanation to their solutions? I've read them really throughly and don't quite understand them. Thanks everyone for their help!

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

Только что решил задачу D при условии, что обменивать можно только соседние ячейки. Глупо было пропустить этот момент в условии, но модифицированная задачка тоже получилась довольно интересной. Рекомендую.

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

Im sorry i can't understand what variable m stands for,

can someone please explain it to me ??

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

There is a similar problem to problem D

"Silly Sort" SPOJ SSORT / 2481 Live Archive / 2002 World Finals ACM

I solved it with the same idea for problem D. The property of that every swap increase or decrease the number of cycles in a permutation(see graph in tutorial) is very useful.

Links:

SSORT

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

    Well, these problems are not similar. They use similar idea, but greedy algorithms are different.

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

      I don't refer for greedy algorithm , in fact i explain in my comment about idea of (that every swap increase or decrease the number of cycles in the graph by one)

      This is the similar.

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

I think this is really a great contest especially the problem D and E.I have never seen these problems and I have learnt a lot from these problems.

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

The case 2 of 441D - Valera and Swaps can be solved in O(N) using stack
Note that the numbers you choose to swap with the same i are always increasing
We can interate through p[i] → p[p[i]] → ... with a stack to maintain a lexicographical-smallest increasing sub-ring
When you pop some elements, you remove a monotonic sub-ring from the current ring, and thus the order to swap for the sub-ring is certian
Just store them, you dont have to recaculate them

Total time complexity: O(N)
See my code 22617043 for details

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

We can do div2 B in O(n) too!! Solution: 6850502

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

We can do div2 problem B in O(n) too!! solution: 65319642

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

Why problem D has tag "string suffix structures"?

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

Can anybody help me in problem B — Valera and Fruits , why my code is not working for test case no. 5 https://codeforces.com/contest/441/submission/236088517