用矩阵进行数列加速

前置知识:

  • 矩阵乘法

  • 快速幂


矩阵快速幂

实际上就是将快速幂中所有乘法换成矩阵乘法即可。

struct matrix{
    ll e[N+11][N+11];
    int row,col;
    matrix(){
        row=col=e[1][1]=1;
    }
    matrix(int p){
        row=col=p;
        register int i,j;
        for(i=1;i<=p;i++)
            for(j=1;j<=p;j++)
                e[i][j]=0;
        for(register int i=1;i<=p;i++)
            e[i][i]=1;
    }
    matrix(int R,int C){
        row=R,col=C;
        register int i,j;
        for(i=1;i<=R;i++)
            for(j=1;j<=C;j++)
                e[i][j]=0;
    }
    void operator = (const matrix B){
        row=B.row ,col=B.col ;
        register int i,j;
        for(i=1;i<=row;i++)
            for(j=1;j<=col;j++)
                e[i][j]=B.e[i][j];
    }
    inline ll at(int r,int c){
        return e[r][c];
    }
    inline void edit(int r,int c,ll k){
        e[r][c]=k;
    }
    inline void add_node(int r,int c,ll k){
        e[r][c]=(e[r][c]+k)%mod;
    }
};

inline matrix mul(matrix A,matrix B)
{
    int n=A.row ,m=B.col ,p=B.row ;
    matrix C(n,m);
    register int i,j,k;
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            for(k=1;k<=p;k++)
                C.add_node(i,j,A.at(i,k)*B.at(k,j)%mod);
    return C;
}

inline matrix fast_pow(matrix A,ll B)
{
    matrix ans(A.row );
    while(B>0)
    {
        if(B%2==1)ans=mul(ans,A);
        A=mul(A,A),B>>=1;
    }  
    return ans;
}

\(\text{Fibonacci}\)数列

看这里:https://www.luogu.org/problemnew/show/P1962

对于 100% 的数据: n在long long(INT64)范围内。

一看就不能用一般的递推。

所以我们考虑用矩阵。

\(\begin{bmatrix}F_{n+1}\\F_n\end{bmatrix}\)

我们令其为目标状态C

\(C\)可以由\(\begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}(B)\)推过来。

怎么推?

如果\(C=A\times B\),那么\(A\)就是一个\(2\times 2\)的方阵。

根据定义,易知:

F[n+1]=F[n]*1+F[n-1]*1;
F[n]=F[n]*1+F[n-1]*0;

结合矩阵乘法的规则,我们有了以下结论:

\[\begin{bmatrix}F_{n+1}\\F_n\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix} \times \begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}\]

所以:

\[\begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix}^{n-2} \times \begin{bmatrix}1\\1\end{bmatrix}\]

Luogu P1939 【模板】矩阵加速(数列)

HERE:https://www.luogu.org/problemnew/show/P1939

题意:定义递推式\(x_n\)

\[x_1=x_2=x_3=1\]

\[x_n=x_{n-3}+x_{n-1}(n>3)\]

我们可以仿照上面Fibonacci数列的推导方式做这道题。

定义目标矩阵\(C=\begin{bmatrix} x_n\\x_{n-1}\\x_{n-2} \end{bmatrix}\)

前一个状态\(B=\begin{bmatrix} x_{n-1}\\x_{n-2}\\x_{n-3} \end{bmatrix}\)

\(C\)中的\(x_{n-1},x_{n-2}\)都可以直接从\(B\)中获取。

\(x_n\)项根据递推式计算即可。

所以,转移矩阵\(A(3\times 3)\)和递推公式就可以得出来了:

\[\begin{bmatrix}x_{n}\\x_{n-1}\\x_{n-2}\end{bmatrix}=\begin{bmatrix}1&0&1\\1&0&0\\0&1&0\end{bmatrix}^{n-3} \times \begin{bmatrix}1(a_3)\\1(a_2)\\1(a_1)\end{bmatrix}\]

[NOI2012]随机数生成器

HERE :https://www.luogu.org/problemnew/show/P2044

题意:定义递推式\(X_n\)

\[X_n=(aX_{n-1}+c)\mod m(n\in[1,10^{18}],n\in\mathbb{Z}^+)\]

然而并不难。

易知第\(n\)项是由第\(n-1\)项推来的。

不妨设\(C=\begin{bmatrix}X_n\\c\end{bmatrix},B=\begin{bmatrix}X_{n-1}\\c\end{bmatrix}\)

首先,\(C\)中的\(X_n\)项可由递推式得到。

所以:

X[n]=a*X[n-1]+1*c;
c=0*X[n-1]+1*c;

\(\therefore A=\begin{bmatrix}a&1\\0&1\end {bmatrix}\)

最终结论:

\[\begin{bmatrix}X_n\\c\end{bmatrix}=\begin{bmatrix}a&1\\0&1\end {bmatrix}^{n}\times\begin{bmatrix}X_{0}\\c\end{bmatrix}\]

转载于:https://www.cnblogs.com/-Wallace-/p/10490219.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值