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

Автор bobr_salavat, история, 11 месяцев назад, По-русски

Предисловие:

Я не утверждаю, что мое решение самое лучшее/простое/оптимальное и на самом деле что оно вообще работает, просто придумал и решил написать сюда. Если у вас есть другое решение, можете предложить его в комментариях. Буду считать что вам знакомы следующие темы: неявное дерево отрезков, массовые операции на дереве отрезков, персистентное дерево отрезков.

Задача:

Дан массив $$$A$$$, из $$$N$$$ целых чисел. Дано $$$Q$$$ запросов двух типов: $$$(1, L, R)$$$ — найти кол-во различных чисел на отрезке, $$$(2, X, D)$$$ — заменить число на позиции $$$X$$$ числом $$$D$$$. Будем считать что на запросы нельзя отвечать оффлайн. $$$1 <= L_i, R_i, X_i <= N, Q, <= 10 ^ 5, 1 <= A_i, D_i <= 10^9$$$.

Решение:

Для начала рассмотрим задачу без обновлений. Будем хранить массив $$$B$$$ размера $$$N$$$, где $$$B_i$$$ — индекс следующего элемента в массиве $$$A$$$ равного $$$A_i$$$, или $$$N+1$$$ если такого не существует. Более формально, $$$B_i = min j: j > i, A_j = A_i$$$, если такой существует или $$$N+1$$$ иначе. Построим на персистентное неявное дерево отрезков, назовем его $$$T$$$, его версии будут храниться в массиве $$$Vers$$$. Пройдемся по массиву для каждого $$$i: 1 <= i <= n$$$ добавим $$$B_i$$$ в $$$T$$$ и сохраним очередную версию в $$$Vers_i$$$. Теперь можно отвечать на запрос количества различных чисел на отрезке. Найдем для каждого значения присутствующего на отрезке $$$A[L:R]$$$, последнее его вхождение в отрезок. Очевидно, что количество таких чисел для всех значений на отрезке — количество различных чисел на отрезке. Найти такое значение очень просто, это лишь количество чисел $$$B_i$$$ на отрезке $$$[L:R]: B_i > R$$$. Найти такое количество можно воспользовавшись идеей префиксных сумм. Найти ответ для префикса длины $$$R$$$, и вычесть ответ на префиксе длины $$$L-1$$$. На префиксе произвольной длины $$$K$$$, можно посчитать ответ спуском по $$$Vers_K$$$ (нумерация с нуля).

Добавим запрос обновления элемента по индексу $$$(2, X, D)$$$. Сначала поймем как меняется массив $$$B$$$. Помимо $$$B$$$, будем хранить в некотором дереве поиска $$$MP$$$ (например std::map) пары $$$(Value, Indices)$$$, где $$$Value$$$ — значение присутствующее в массиве $$$A$$$, $$$Indices$$$ — все индексы $$$i: A_i = Value$$$, в отсортированном порядке, при этом в $$$MP$$$ будет сортировка только по $$$Value$$$. Теперь изменение значения $$$V$$$ = $$$A_X$$$, равносильно удалению $$$MP_V$$$ из $$$MP_D$$$, и вставить $$$X$$$ в $$$MP_D$$$. Рассмотрим операцию удаления из $$$Indices$$$. Пусть $$$X1$$$ — число слева от $$$X$$$ в $$$Indices$$$ (если оно существует), т.е. максимально меньшее $$$X$$$, $$$X2$$$ — число справа от $$$X$$$ (если оно существует, иначе $$$N+1$$$), т.е. минимальное большее $$$X$$$. Тогда массив $$$B$$$ изменится так: $$$B_X1$$$ = $$$X2$$$. Рассмотрим операцию добавления числа в $$$Indices$$$. Пусть $$$X1$$$ — число слева от $$$X$$$ в $$$Indices$$$ (если оно существует), т.е. максимально меньшее $$$X$$$, $$$X2$$$ — число справа от $$$X$$$ (если оно существует, иначе $$$N+1$$$), т.е. минимальное большее $$$X$$$. Тогда массив $$$B$$$ изменится так: $$$B_X1 = X, B_X = X2$$$.

Теперь осталось научиться делать делать изменения в версиях T. На каждый запрос изменения числа в T нам необходимо изменить $$$O(log N)$$$ вершин, следовательно на запрос изменения изменится $$$O(log N)$$$ вершин. При изменении вершины будем записывать в некоторый массив, созданный для каждой вершины нулевой версии, размера равного количеству версий конкретной вершины и при запросе получения значения в вершине, просто брать сумму на префиксе до соответствующей версии. Так, нужно хранить все версии в структуре, поддерживающей следующие операции: добавление элемента в конец, получение суммы на префиксе, изменение в точке. Нам подходит дерево фенвика, каждую операцию выполняет за $$$O(log N)$$$, и не ухудшает память. По итогу, все операции мы сделаем за $$$O((N + Q) log^2 N)$$$ времени и $$$O((N+Q)logN)$$$ памяти.

P.S. Задачу лень искать, мб сам сделаю потом.

Полный текст и комментарии »

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

Автор bobr_salavat, 12 месяцев назад, По-русски

Задача:

Даны два массива $$$A$$$, $$$B$$$ длин $$$N$$$. Требуется найти их наибольшую по длине общую подпоследовательность.

Решение:

Задача поиска наибольшей общей подпоследовательности двух массивов $$$A$$$ и $$$B$$$ длин $$$N$$$ и $$$N$$$ соответственно решается в общем случае за $$$O(N^2)$$$. Но задачу можно решить за $$$O(N log N)$$$, если в одном из массивов все элементы уникальны, без ограничения общности будем считать, что в массиве $$$А$$$.

Построим массив $$$C$$$ длины $$$N$$$ такой, что $$$C_i$$$ — индекс элемента $$$B_i$$$ в массиве $$$A$$$, или $$$-1$$$ если такого элемента нет в массиве $$$А$$$. Такой массив можно легко построить за $$$O(N log N)$$$, используя сортировки. Тогда очевидно что общей подпоследовательности $$$A$$$ и $$$B$$$ будет соответствовать некоторая возрастающая подпоследовательность массива C. Таким образом, найти ответ можно стандартным алгоритмом поиска наибольшей возрастающей подпоследовательности за $$$O(N log N)$$$, игнорируя при этом элементы равные $$$-1$$$.

Полный текст и комментарии »

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

Автор bobr_salavat, история, 14 месяцев назад, По-русски

Планарный граф

Планарный граф — граф который можно изобразить на плоскости без пересечения ребер (кроме как в вершинах). Существует критерий планарности: граф планарен тогда и только тогда, когда он не содержит подграфы $$$K_5$$$ и $$$K_3,_3$$$. Где $$$K_5$$$ — полный граф на 5 вершинах, $$$K_3,_3$$$ полный двудольный граф на 6 вершинах (по 3 в каждой доле).

Формула Эйлера

Если граф на $$$V$$$ вершинах с $$$E$$$ ребрами планарен, то количество граней, на которые граф разбивает плоскость $$$F = E - V + 2$$$. Попробуйте доказать самостоятельно.

Полный текст и комментарии »

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

Автор bobr_salavat, история, 14 месяцев назад, По-русски

Кто нибудь знает как сделать 2д декартово дерево по неявному ключу. Можете объяснить или скинуть ссылки по теме?

Полный текст и комментарии »

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