|
Кружок обучения мастерству программирования при СПбГУ |
Лекции группы A0 - Лекция 03 - про алгоритм 4-х русских
Note: Звездочкой отмечены темы, на которые на лекции времени не хватило.
Краткий план лекции на тему "Алгоритм 4-х русских"
- Перемножение матриц
- Задача про построение булевой функции
- Быстрые RMQ алгоритмы
- Наибольшая общая подпоследовательность
- СНМ
- * Задача про добавляющиеся и удаляющиеся ребра
- Сортировка Шелла
- * Умножение чисел
Полный план лекции
- Перемножение матриц
- Алгоритм за O(n^3), стандартные не асимптотические оптимизации
- Алгоритм Штрассена [r=2, a=7] за O(n^{2.807}), оптимизация Винограда (15 сложений вместо 18-и)
- Алгоритм Пана [r=70, a=143640] за O(n^{2.796}), сложность = n^[log_r{a}], док-во
- Алгоритм Копперсмита — Винограда за O(n^{2.375})
- Использование теории групп для получения алгоритма за O(n^{2.48})
- Использование битового сжатия для бинарных матриц - O(n^3 / logn)
- Использование алгоритма 4-х русских для бинарных матриц - O(n^3 / (logn)^2)
- Умножение матриц за O(n^2 / logn) :-D
- Плюс по сравнению с обычным битывым сжатием - возможность умножать битовую на не битовую
- Деление = Обращение = Решение систем >= Умножение
- Задача про построение булевой функции
- Решение за [2^n * n]. КНФ + предподсчитать ~x.
- Решение за [2^(n+1)]. Раскрытие скобок в КНФ.
- Применение идеи 4-х русских, O(2^n / n). Оптимайз с хэшированием ВСЕХ состояний.
- Быстрые RMQ алгоритмы
- За [O(logn), O(n)] с помощью дерева отрезков
- За [O(1), O(nlogn)] с помощью таблички
- За [O(loglogn), O(n)] и [O(log*n), (O(nlog*n)] комбинируя эти методы
- Наибольшая общая подпоследовательность
- Классическое решение за O(n^2)
- Оптимизация с помощью 4-х русских до O(n^2 / (logn)^2)
- СНМ
- Простая реализация с color[v], [O(m), O(n^2)]
- Оптимизация перекраски меньшего множества [O(m), O(nlogn)]
- Подвешивание [O(mn), O(n)]
- Подвешивание меньшего к большему [O(mlogn), O(n)], пример с =mlogn, док-во
- Сжатие путей [O(mlogn), O(n)], пример с =mlogn, без док-ва того, что работает O(mlogn)
- * Объединение двух эвристик, алгоритм за [O(m*), O(n)], док-во через крутые ребра
- Реализация W за [O(m), O(n)] в предположении того, что дерево объединения известно заранее
- Разбиение подвешенного дерева на куски размера [2..2k) с общим родителем. Добавление к лесу фиктивного корня.
- Собственно идея 4-х русских : внутри куска запрос выполняется за O(1). Предподсчет = upp[tree, a]
- Кусков n / k. Из их корней сделали дерево, на нем реализовали алгоритм [O(m), O(nlogn)]
- Запрос get(a) = micro + macro + micro. Если micro(x) != micro(macro), нужно делать join в macro
- Операция link(v, parent[v]) = добавить ребро в micro-tree с помощью битовых масок за O(1)
- Хранение micro-tree. Строим лес [или переходим к следующей вершине, или вешаем на эту] => нужно 2k-2 бит. k = O(logn) => [O(m), O(n)]
- Применение реализации W для получения LCA-Offline за O(n+m)
- * Задача про добавляющиеся и удаляющиеся ребра
- * Только добавление = СНМ
- * Только удаление = СНМ (в обратном порядке => добавление)
- * При фиксированном дереве получаем Add = Del = Get = O(logn) = запрос к дереву отрезков для суммы
- * Добавление + Удаление = СНМ + корневая эвристика [O(V)]
- Сортировка Шелла
- Сортировка вставками. Число операций = O(n) + число инверсий
- K-сортированный массив. A-сортированный массив после B-сортировки остается A-сортированным (swap-ы можно делать в любом порядке)
- (A,B)=1, массив A,B-отсортирован => Время X сортировки = A*B*N / X
- Результат про (AB - A - B + 1) / 2 чисел, которые нельзя получить, как Ax + By (x, y >= 0)
- h[k] = 2^k - 1 => Time = O(n^{3/2})
- Последовательность 2^s * 3^t дает время O(n(logn)^2)
- * Умножение чисел
- * За O(mlen^2) + O(nm) умножений + O(n+m) делений
- * Карацуба = O(n^log3)
- * Аццкий метод за O(n^{1+eps}) с интерполяцией и экстерполяцией за O(1)