Используя теорему Кейли-Гамильтона , мы можем быть быстрее.Теорема утверждает, что каждая матричная степень для размерности k
может быть записана как сумма первых k
степеней A
.
Если мы знаем это, мы можем использовать возведение в степень путем возведения в квадрат, но вместоработая с матрицами, мы работаем над полиномами над A
с коэффициентами в ℤ.Затем мы можем после каждого шага уменьшить многочлен на характеристический многочлен.
В качестве небольшого примера:
A = [[1, 1],
[1, 0]]
A^2 = A + 1 = writing poly. coefficients = {1, 1}
pow(A, 15) = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
= {1, 0} * ({1, 0} * ({1, 0} * {1, 0}^2)^2)^2
= {1, 0} * ({1, 0} * ({1, 0} * {1, 0, 0})^2)^2
= {1, 0} * ({1, 0} * ({1, 0} * {1, 1})^2)^2
= {1, 0} * ({1, 0} * ({1, 1, 0})^2)^2
= {1, 0} * ({1, 0} * {2, 1}^2)^2
= {1, 0} * ({1, 0} * {4, 4, 1})^2
= {1, 0} * ({1, 0} * {8, 5})^2
= {1, 0} * ({8, 5, 0})^2
= {1, 0} * {13, 8}^2
= {1, 0} * {169, 208, 64}
= {1, 0} * {377, 233}
= {377, 233, 0}
= {610, 377}
= [[987, 610],
[610, 377]]
Итак, каковы затраты времени выполнения?Тривиально O(k^2 * log n)
, потому что на каждом шаге возведения в квадрат нам нужно вычислить квадрат двух полиномов и уменьшить на символ.многочлен.Использование аналогичного трюка с @harold в другом ответе дает O(k log k log n)
с использованием умножения дискретных полиномов Фурье, поскольку мы можем найти примитивные корни.