123789456ye

已AFO

快速幂与矩阵快速幂

利用二进制拆分可将形如求\(a^{n}\)的问题的复杂度从\(O(n)\)降至\(O(\log n)\)
可求出\(a\),\(a^{2}\),……,\(a^{k}\)
若n的二进制表示下的第k位为1则乘上\(a^{k}\),否则跳过
自然语言是多么无力啊
看代码会比较好

int ksm(int a,int n)
{
    int ans=1;
    while(n)
    {
        if(n&1) ans*=a;//求出当前的最后一位是否为1
        a*=a;
        n>>=1;//舍弃掉最后一位,原来的第k位变为k-1位(其实就是左移)
    }
    return ans;
}

我们可以用快速幂的思想来解决掉一些递推问题
例子:fibbonaci数列第n项
其定义为

\[ f(x)=\left \{ \begin{aligned} & 1 & i=1,2 \newline & f(i-1)+f(i-2) & i>2 \end{aligned} \right. \]

显然用记忆化只能将复杂度降到\(O(n)\)
显然有

\[ \left[ \begin{matrix} 1 & 1 \newline 1 & 0 \newline \end{matrix} \right] * \left[ \begin{matrix} f[i-1] \newline f[i-2] \end{matrix} \right] = \left[ \begin{matrix} f[i] \newline f[i-1] \end{matrix} \right] \]

markdown矩阵好难打啊
因此有

\[\left[ \begin{matrix} f[i] \newline f[i-1] \end{matrix} \right] = \left[ \begin{matrix} 1 & 1 \newline 1 & 0 \newline \end{matrix} \right]^{i-1} * \left[ \begin{matrix} f[2] \newline f[1] \end{matrix} \right] \]

这和上面的快速幂形式是一样的
因此我们称其为矩阵快速幂
上代码

struct Matrix
{
    int a[2][2];
    void clear()
    {
        memset(a,0,sizeof(a));
    }
    int* operator [] (const int x)
    {
        return a[x];
    }
    friend Matrix operator * (Matrix a,Matrix b)
    {
        Matrix c;
        c.clear();
        for(int k=0;k<2;++k)
            for(int i=0;i<2;++i)
                for(int j=0;j<2;++j)
                    c[i][j]+=a[i][k]*b[k][j];
        return c;
    }
}base,ans;

base初始化为要乘的矩阵,ans初始化为初值(即左边那条线为1,右边为0)
这种问题的难点就是要推出要乘的矩阵,推出来了就好办了
板子题洛谷P1962

posted @ 2019-06-21 20:46  123789456ye  阅读(106)  评论(0编辑  收藏  举报