Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Структура данных.лекция.doc
Скачиваний:
0
Добавлен:
30.07.2019
Размер:
251.39 Кб
Скачать

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. Интересного Вам чтения!