Быстрое умножение

Рассмотрим не только многочлены, но и функции.

Алгоритм Карацубы

Пусть мы хотим посчитать произведение двух многочленов P(x)=k=0npkxkP(x) = \sum\limits_{k=0}^n p_k \cdot x^k и Q(x)=k=0nqkxkQ(x) = \sum\limits_{k=0}^n q_k \cdot x^k.

Попробуем применить метод «разделяй и властвуй», чтобы добиться временной сложности меньшей, чем O(n2)O(n^2). В лоб, к сожалению, не получится. Применим хитрость.

Сгруппируем множители в многочленах PP и QQ степени n=2kn = 2k, превратив каждый многочлен в пару многочленов степени kk.

P(x)=a(x)+xkb(x)иQ(x)=c(x)+xkd(x)P(x) = a(x) + x^k \cdot b(x) \quad\text{и}\quad Q(x) = c(x) + x^k \cdot d(x)

Произведение P(x)Q(x)P(x) \cdot Q(x) можно произвести, используя только 33 умножения маленьких многочленов, вместо привычных 44:

P(x)Q(x)=(a+xkb)(c+xkd)=ac+xk((a+b)(c+d)acbd)+x2kbdP(x) \cdot Q(x) = \bigl( a + x^k \cdot b \bigr) \cdot \bigl( c + x^k \cdot d \bigr) = a c + x^k \cdot \bigl( (a + b) \cdot (c + d) - a c - b d \bigr) + x^{2 k} \cdot b d
function karatsuba(array[int] p, array[int] q): ...

Анализ алгоритма

При таком алгоритме на итерацию требуется 33 умножения и 66 сложений. Пусть алгоритм, вычисляющий произведение двух многочленов степени nn, требует M(n)M(n) умножений и A(n)A(n) сложений.

Оценим количество умножений. Как мы уже говорили, можно дополнить многочлены нулями до длины 2log2n+12^{\lfloor \log_2 n \rfloor + 1}. Тогда вычисления будут проще, но количество умножений возрастет.

M(n)={1 if n=02M(n/2)+M(n/21) otherwise илиMгрубое(n)=3log2n+1M(n) = \cases{ 1 & \if n = 0 \\ 2 \cdot M ( \lfloor n/2 \rfloor ) + M ( \lceil n/2 \rceil - 1 ) & \otherwise } \quad\text{или}\quad M_{\text{грубое}}(n) = 3^{\lfloor \log_2 n \rfloor + 1}
Дополнение нулями до 2log2n+12^{\lfloor \log_2 n \rfloor + 1} достаточно неэффективное

Важное неравенство, позволяющее оценить количество требуемых умножений

nlog23M(n)3nlog23n^{\log_2 3} \le M(n) \le 3 \cdot n^{\log_2 3}

То есть, алгоритм Карацубы (в обоих вариантах, с дополнениями нулями и без) требует Θ(nlog23)\Theta \bigl( n^{\log_2 3} \bigr) умножений.

Оптимизации

Накладные расходы на рекурсию иногда становятся слишком большими. Можно выполнять алгоритм Карацубы только пока степени многочленов больше какого-то числа NmaxN_{\max\limits}. Для многочленов, чьи степени меньше NmaxN_{\max\limits}, выполняем обычное умножение.

На практике NmaxN_{\max\limits} выбирают 3232 или 6464.

Алгоритм Тоома-Кука