Найти тему

Префиксные и суффиксные суммы

Оглавление

Всем доброго времени суток!

Не знаю, как подступиться к этой теме, поэтому сразу начнем с примера.

-2

Как это можно сделать? Давайте будем разбираться...

Первая мысль

Ну, проще всего заюзать питоновские функции.

-3

А вообще, если вы не знаете эти функции, то можете сами что-нибудь забацать. Например это:

-4

Первый и второй алгоритмы работают со сложностью O(n), n = r - l + 1 (длина отрезка).

Усложним задачу

А теперь представьте, что вам нужно посчитать сумму на отрезке очень-очень много раз, ну, скажем, 10 000 раз для массива размером 100 000, тогда в худшем случае нам придется выполнить 10e9 операций. Это плохо... Как бы ускорить подсчет суммы на отрезке...

Но сначала, что такое префикс и суффикс.

Префикс - это подмассив с 0 до p.

Суффикс - подмассив с s до len(lst) - 1.

Слушайте... А что если мы рассмотрим префикс массива до l - 1 и до r.

-5

Кажется, сумма на зеленом префиксе минус сумма на синем будет равна сумме на отрезке... Да? Даа!

Как посчитать сумму на префиксе... очень просто, думаю вы и так это сможете это сделать!

Мы можем запомнить все суммы на префиксах в массиве s, в котором s[p] = sum(a[:p + 1]).

-6

Чему теперь будет равна сумма от l до r (sum(lst[l: r + 1]))?

-7

Мы считаем это за O(1), понимаете? Это победа... только не забудьте проверить крайние значения индексов...

Если вы не до конца поняли, что мы сделали, посмотрите внимательно на картинку с экселем :)

Такие дела... Что-то аналогичное можно сделать и с суффиксами. Просто считать нужно будет с конца.

Еще задачка

Теперь нам нужно быстро отвечать на запросы: "Сколько элементов больших V = const на отрезке от l до r?"

Ну, по аналогии делаем... хихи))

-8

Вывод

Вообще, мы можем применять этот метод всегда, когда речь идет об операции, имеющей обратную (+-, */)... вроде....

Ну вот и все

Будте счастливы! Покасики!!