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

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

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
  • Проголосовать: не нравится

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

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

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

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

»
12 лет назад, скрыть # |
 
Проголосовать: нравится 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 и посчитать матожидание.

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

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

    • »
      »
      »
      12 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 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].
      Итоговая сложность .

      • »
        »
        »
        »
        12 лет назад, скрыть # ^ |
        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 (вроде это уже даже многовато).

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

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

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

When will english translations be available?

»
12 лет назад, скрыть # |
 
Проголосовать: нравится +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!

»
12 лет назад, скрыть # |
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?

»
12 лет назад, скрыть # |
 
Проголосовать: нравится 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?

»
12 лет назад, скрыть # |
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.

»
12 лет назад, скрыть # |
 
Проголосовать: нравится 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??

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

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

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

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

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

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

can someone please explain it to me ??

»
12 лет назад, скрыть # |
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

»
12 лет назад, скрыть # |
 
Проголосовать: нравится 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.

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 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

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

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

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

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

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

Why problem D has tag "string suffix structures"?