- •Структуры данных
- •Insert (X) – добавляет в очередь новый объект X;
- •Init (n) – инициализировать систему непересекающихся множеств, поместив в нее набор из n непересекающихся множеств – по одному множеству для каждого объекта.
- •Init (n) – заполнить таблицу a[1..N] нулями.
- •Init (n) – установить значения в таблице a[1..N], равными бесконечности.
- •Init (n);
- •Init (n) – инициализирует систему (все парковочные места свободны);
- •Init (c);
- •Init (c);
Init (c);
For i:= 1 to EventCnt-1 Do Begin
MODIFY (Event[i].y1+1, Event[i].y2, Event[i].value);
S:= S + (Event[i+1].x - Event[i].x) * (C – FINDCOVER (1, C));
End;
OUTPUT (S);
End;
Пример 2. Рассмотрим следующую задачу MAXSQUARE. Предположим, что имеется таблица T[1..C, 1..C]. Почти все элементы таблицы равны нулю, за исключением N ячеек T[X1, Y1], T[X2, Y2], …, T[XN, YN], которые равны 1. Далее мы считаем, что ячейка T[1,1] – левый нижний угол таблицы, а ячейка T[C, C] – правый верхний. Необходимо найти квадратную область таблицы со стороной в t ячеек, сумма элементов в которой максимально возможна (естественно, что t ≤ C). Уточним входные данные в этой задаче: это величины C, t, N, X1, Y1, …, XN, YN (полностью значения в таблице не задаются, достаточно задать только ненулевые значения). В качестве ответа будем выводить сумму ячеек таблицы в найденной области. Мы описываем алгоритм решения задачи, время работы которого равно O((N+С)(logN+logC)), а расходы памяти составят O(N+C) байт.
Для решения мы используем вспомогательный массив списков List[1..C]. Ячейка List[x] содержит список всех Yi, таких, что Xi = x (то есть, список ординат всех единичных ячеек таблицы T с заданной абсциссой). Построить списки List несложно за время O(NlogN+C), и они занимают O(N+C) байт памяти. Идея решения такова: мы рассматриваем интервал абсцисс [x, x+t-1], начиная с x = 1 и постепенно увеличивая x. Кроме того мы поддерживаем таблицу A[1..C] (точнее, поддерживаем информацию о ней при помощи дерева максимумов), в которой элемент A[y] равен сумме ячеек в квадратной области со стороной длины t с левым нижним углом в ячейке T[x, y] (для текущего значения x). Если x фиксировано, то с помощью запроса FINDMAX (1, C) мы можем найти максимальную сумму ячеек во всех квадратных областях со стороной длины t и абсциссой левого нижнего угла, равной x. При увеличении x информацию в таблице A нужно обновлять, так как некоторые единичные ячейки выходят из рассматриваемого интервала, а некоторые, наоборот, входят. Для обновления мы используем операцию MODIFY. Алгоритм записывается следующим образом:
Algorithm MAXSQUARE
Init (c);
For x:= 1 to t-1 Do Begin
L:= List[x];
While L <> NIL Do Begin
MODIFY (max(1, L^.y-t+1), L^.y, 1);
L:= L^.Next;
End;
End;
Res:= 0;
For x:= 1 to C-t+1 Do Begin
L:= List[x+t-1];
While L <> NIL Do Begin
MODIFY (max(1, L^.y-t+1), L^.y, 1);
L:= L^.Next;
End;
Res:= max(Res, FINDMAX (1, C));
L:= List[x];
While L <> NIL Do Begin
MODIFY (max(1, L^.y-t+1), L^.y, -1);
L:= L^.Next;
End;
End;
OUTPUT (Res);
End;
Упражнение 20 (*). В эти лекции планировалось включить еще один раздел о решении задач LCA и RMQ за время (O(N), O(1)). Однако этот материал прямого отношения к структурам данных не имеет, и, к тому же, полученные лекции и так довольно велики. Поэтому этот материал оставляется (для желающих) на самостоятельное изучение. Вам поможет статья LCA Revisited, в которой описывается (самими авторами) алгоритм Фарака-Бендера и Колтона решения задачи LCA за (O(N), O(1)). Эту статью можно найти на сайте http://shade.msu.ru/~mab. Интересного Вам чтения!