并不对劲的矩阵快速幂

在正式开始之前,先讲一下看上去没什么意义的矩阵乘法。

对于大小为n*m大小的矩阵A和大小为m*k的矩阵B相乘,答案是一个n*k的矩阵C,满足:

c[i][j]=sum{a[i][l]*b[l][j] | 1<=i<=n,1<=l<=m,1<=j<=k};

typedef struct node
{
    int mat[210][210];
} Matrix;
Matrix mul(Matrix a,Matrix b)
{
    Matrix c;
    memset(c.mat,0x3f,sizeof(c.mat));
    for(int k=1; k<=siz; k++)
    {
        for(int i=1; i<=siz; i++)
        {
            for(int j=1; j<=siz; j++)
            {
                c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
            }
        }
    }
    return c;
}

这个东西有什么用呢?

*********************************正式开始的分界线************************************

有时递推式又臭又长(主要是时间复杂度,不是长得多恶心),怎么办?

这个时候,就要用一个看似很高能的东西了:递推矩阵。将状态和递推公式转化成矩阵的形式,使得每往后推一步,都相当于让状态矩阵乘一次递推矩阵(<-我瞎编的名),也就是大概这个样子:初始状态*递推矩阵*递推矩阵*……。稍作变换,得到第n步的状态就是:初始状态*(递推矩阵)^n。

现在,只要将  (递推矩阵)^n 快速地算出来就行了。这跟普通的快速幂就没什么区别了。

void pow(int tim)
{
    while(tim)
    {
        if(tim&1)
            ans=mul(ans,tmp);
        tmp=mul(tmp,tmp);
        tim>>=1;
    }

}
View Code
原文地址:https://www.cnblogs.com/xzyf/p/8039193.html