← Назад к математике

Матричное умножение Фибоначчи

Вычисление чисел Фибоначчи за O(log n) через возведение матрицы в степень

🐍 Python
def mat_mult(A, B):
    return [
        [A[0][0]*B[0][0] + A[0][1]*B[1][0], A[0][0]*B[0][1] + A[0][1]*B[1][1]],
        [A[1][0]*B[0][0] + A[1][1]*B[1][0], A[1][0]*B[0][1] + A[1][1]*B[1][1]]
    ]

def mat_pow(M, n):
    result = [[1, 0], [0, 1]]
    while n > 0:
        if n & 1:
            result = mat_mult(result, M)
        M = mat_mult(M, M)
        n >>= 1
    return result

def fib(n):
    if n <= 1:
        return n
    M = [[1, 1], [1, 0]]
    return mat_pow(M, n-1)[0][0]

n = int(input())
print(fib(n))
⚙️ C++
#include <bits/stdc++.h>
using namespace std;

struct Matrix {
    long long a, b, c, d;
    Matrix(long long a=1, long long b=0, long long c=0, long long d=1) 
        : a(a), b(b), c(c), d(d) {}
};

Matrix multiply(const Matrix& A, const Matrix& B) {
    return Matrix(
        A.a*B.a + A.b*B.c,
        A.a*B.b + A.b*B.d,
        A.c*B.a + A.d*B.c,
        A.c*B.b + A.d*B.d
    );
}

Matrix power(Matrix M, long long n) {
    Matrix result;
    while (n > 0) {
        if (n & 1) result = multiply(result, M);
        M = multiply(M, M);
        n >>= 1;
    }
    return result;
}

long long fib(long long n) {
    if (n <= 1) return n;
    Matrix M(1, 1, 1, 0);
    return power(M, n-1).a;
}

int main() {
    long long n;
    cin >> n;
    cout << fib(n) << endl;
    return 0;
}

Как работает матричное умножение Фибоначчи?

Числа Фибоначчи можно вычислить с помощью возведения матрицы в степень:

[F(n+1) F(n) ] = [1 1]n
[F(n) F(n-1)] [1 0]

Таким образом, F(n) равно элементу в левом верхнем углу матрицы, возведённой в степень n-1.

Почему это работает?

Матрица M = [[1, 1], [1, 0]] обладает свойством:

M · [F(n), F(n-1)]T = [F(n+1), F(n)]T

Возведение в степень n даёт Mⁿ, которая умножает начальный вектор [F(1), F(0)] = [1, 0].

Преимущество

Бинарное возведение в степень выполняется за O(log n) умножений матриц 2×2, что значительно быстрее O(n) итеративного метода для больших n.

Временная сложность: O(log n)

Формат ввода и вывода

Ввод: n — номер числа Фибоначчи (0-индексация)

Вывод: F(n)

Пример:

10

Вывод: 55

Ряд Фибоначчи: F(0)=0, F(1)=1, F(2)=1, F(3)=2, F(4)=3, F(5)=5, F(6)=8, F(7)=13, F(8)=21, F(9)=34, F(10)=55

Попробовать онлайн

Результат появится здесь...