zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    (1)矩阵乘法

    简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C


    其中c[i][j]为A的第i行与B的第j列对应乘积的和,即:

    另外,矩阵也可以用一个结构体来表示

    struct matrix
    {
        ll a[N][N];
    };

    矩阵乘法代码实现:

    matrix mul(matrix x,matrix y)
    {
        matrix temp;
        for(int i = 1 ; i < N ; i++)
            for(int j = 1 ; j < N ; j++)
            temp.a[i][j] = 0;
        for(int i = 1 ; i < N ; i++)
            for(int j = 1 ; j < N ; j++)
                    for(int k = 1 ; k < N ; k++)
                        temp.a[i][j] += x.a[i][k]*y.a[k][j];
        return temp;
    }

    这个实现代码复杂度是O(n^3)的,其实还有更低复杂度的算法实现。利用分块矩阵即可,比较复杂。。不多说了。

    (2)矩阵快速幂

    类似于整数的快速幂,把整数快速幂中的整数换成矩阵、乘法换成矩阵乘法就可以了。

    代码实现:

    matrix quickpow(matrix a,long long n)
    {
        matrix res;
        res.a[1][1] = 1; res.a[1][2] = 0; res.a[1][3] = 0;
        res.a[2][1] = 0; res.a[2][2] = 1; res.a[2][3] = 0;
        res.a[3][1] = 0; res.a[3][2] = 0; res.a[3][3] = 1;//初始化为单位矩阵
        while(n)
        {
            if(n&1) res = mul(res,a);//判断n是否为奇数
            a = mul(a,a);
            n>>=1;//二分
        }
        return res;
    }

    (3)应用

    通过改变转移矩阵的值,将普通递推式改写成矩阵形式。然后用快速幂求解最终矩阵。

    给一道简单例题:poj 3070 http://poj.org/problem?id=3070

    题目:斐波那契数列f(n),给一个n,求f(n)%10000,n<=1e9;(本题是可以用递推完成的,且可以用记忆化数组的方法加速递推,这里略去不做解释)

    解法:先列出Fibonacci递推式: f(1) = 1.f(2) = 2. f(n) = f(n-1) + f(n-2)  (n > 2) 

    接下来建立矩阵形式的递推,找到转移矩阵,记作T*A(n-1) = A(n).(可以推出1*f(n-1)+1*f(n-2)=f(n);1*f(n-1)+0*f(n-2)=f(n-1);)

    得出最终矩阵A(n) = Tn-1*A(1),这里的A(1)成为初始矩阵,接下来利用矩阵快速幂就可以得到res,res[1][1]=f(n)就是我们要求的。

    给一些简单的递推式
    1.f(n)=a*f(n-1)+b*f(n-2)+c;(a,b,c是常数)


    2.f(n)=c^n-f(n-1) ;(c是常数)

  • 相关阅读:
    P1032 字串变换
    P3203 [HNOI2010]弹飞绵羊
    P3690 【模板】Link Cut Tree (动态树)
    P2147 [SDOI2008]洞穴勘测
    P3950 部落冲突
    Codeforces Round #469 Div. 2题解
    线段树
    SDOI2018退役记
    4.1模拟题
    无旋Treap
  • 原文地址:https://www.cnblogs.com/zz990728/p/8886836.html
Copyright © 2011-2022 走看看