Лекция dfs, DP, 2 указателя
- De Bruijn sequence
- Напоминаем определения: гамильтонов цикл, Эйлеров цикл
- Задача #1: построить цикл на всех строках длины n над алфавитом k.
- Задача #2: построить цикл на всех строках длины n над алфавитом k, в которых четное число нулей.
- Задача про ориентацию графа: ориентировать граф так, чтобы максимальная исходящая степень была минимальна.
- Решение: ориентируем как-нибудь + метод локальных оптимизаций
- Другая идея: бинарный поиск по ответу.
- Оценка времени работы решения с бинарным поиском по ответу: O(E2logD) (logD = BS, dfs = O(E), E − максимальное число итераций)
- Доказательство корректности: если нет пути из вершины степени больше D в вершину степени меньше D, то ответ хотя бы D.
- Метод двух указателей:
- Задача про профессора и яйца, решние за O(nlogn)
- Состояние: [n,k], k ≤ logn. Переход: разделение отрезка на два.
- Даны m запросов "Количество различных чисел на отрезке [Li,Ri]". Offline задача.
- Пусть Li и Ri не убывают, решение за O(n) операций с хеш-таблицей.
- Пусть теперь Li и Ri произвольны, решение за O(nlogn) + O(n3/2) (без рандомизации).
- Переход методом двух указателей: f[n+1,k] ≥ f[n,k]. Максимум двух функций. Поиск p[n,k] циклом while.
- Задача про выбор двух точек на прямой, решение за O(nlogn)
- Сортируем точки. pos[n] ↑ (самая левая точка такая, что сумма слева ≥ суммы справа)
- Перебираем разделитель. Для суффикса и префикса знаем оптимум. Частичные суммы.
- Задача про k точек на прямой
- Решение за O(n2k) с предподсчетом всего, что нужно.
- Решение за O(n2). Само решение − перебирать p[n,k] от p[n,k+1] до p[n+1,k]. Доказательство времени работы ∑ (p[n+1,k]-p[n,k+1]) = O(n2).
- Корректность решения
- f[n,k] ≤ f[n+1,k], f[n,k-1]. Граница отрезка и центр отрезка монотонно зависят друг от друга.
- p[n+1,k] ≥ p[n,k] (возьмем решение [n,k], последний отрезок удлиним, перейдем к оптимальному [n+1,k], последний отрезок укоротим, заметим: последнее уменьшени меньше первого увеличения).
- p[n,k-1] ≥ p[n,k] (для k=2 можем найти оптимальную границу циклом while: двигать, пока сумма слева меньше. для k=3 противоречие строится так: A,B,C и D,E границу B,C было двигать не выгодно, значит, граница D,E не дальше границы B,C т.к. сумма слева только увеличилась)