线性代数 —— 矩阵快速幂

【概述】

矩阵快速幂利用矩阵的乘法与整数快速幂的结合,能够快速的算出 n 阶方阵 A 的 M 次幂 A^b,其结果仍是一个矩阵,无具体含义,在信息学竞赛中,矩阵快速幂常用于求解线性递推关系。

关于矩阵的基础知识:点击这里

关于线性递推关系:点击这里

【n*m 矩阵的快速幂】

struct Matrix{
    LL s[N][N];
};
Matrix e;//单位矩阵E
Matrix x;//构造矩阵
void init(int n){
    for(int i=1;i<=n;i++)//主对角线为1
        e.s[i][i]=1;
}
Matrix mul(Matrix A,Matrix B,LL n){//矩阵乘法,n代表A、B两个矩阵是n阶方阵
    Matrix temp;//临时矩阵,存放A*B结果

    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            temp.s[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.s[i][j]=((temp.s[i][j]+A.s[i][k]*B.s[k][j])%MOD+MOD)%MOD;
    return temp;
}
Matrix quickPower(Matrix a,LL b,LL n){//矩阵快速幂,求n阶矩阵a的b次幂
    Matrix ans=e;
    while(b){
        if(b&1)
            ans=mul(ans,a,n);//ans=e*a
        a=mul(a,a,n);//a=a*a
        b>>=1;
    }
    return ans;
}
int main(){
    LL n,m; //构造矩阵的大小、阶
    scanf("%lld%lld",&n,&m);
    init(n);//单位矩阵初始化

    for(int i=1;i<=n;i++)//输入构造矩阵,也可通过题目的递推公式来构造矩阵
        for(int j=1;j<=n;j++)
            cin>>x.s[i][j];

    Matrix res=quickPower(x,m,n);

    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            printf("%lld ",res.s[i][j]);
        printf("\n");
    }

    return 0;
}

【1*n 矩阵的快速幂】 

struct Matrix{
    LL s[N];//1*n的矩阵
};
Matrix e;//单位矩阵E
Matrix x;//构造矩阵x
void init(int n){//单位矩阵的第一行
    for(int i=1;i<=n;i++)
        e.s[i]=0;
    e.s[1]=1;
}
Matrix mul(Matrix A,Matrix B,LL n){//矩阵乘法
    Matrix temp;//临时矩阵,存放矩阵A*矩阵B的结果
    for(int i=1;i<=n;i++)
        temp.s[i]=0;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            temp.s[i]=(temp.s[i]+(A.s[j]*B.s[i-j+1])%MOD)%MOD;

    return temp;
}
Matrix quickPower(Matrix A,LL k,LL n){//矩阵快速幂
    Matrix res=e;
    while(k){
        if(k&1)
            res=mul(A,res,n);//res=A*e
        A=mul(A,A,n);//A=A*A
        k>>=1;
    }
    return res;
}
int main(){
    LL n,k;
    scanf("%lld%lld",&n,&k);
    init(n);
    
    for(int i=1;i<=n;i++)//构造矩阵初始值,根据题目要求推导
        x.s[i]=1;

    Matrix res=quickPower(x,k,n);//k次幂

    for(int i=1;i<=n;i++)
        printf("%d ",res.s[i]);
    printf("\n");

    return 0;
}

【矩阵 1~k 次幂的和】

原理:二分求和

  • 当 n 是奇数时:f(n)=f(n-1)+A^n
  • 当 n 是偶数时:f(n)=f(\frac{n}{2})*(A^{\frac{n}{2}}+E)
struct Matrix{
    LL s[N][N];
};
Matrix add(Matrix A,Matrix B){//A+B
    Matrix temp;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            temp.s[i][j]=(A.s[i][j]+B.s[i][j])%mod;
    return temp;
}
Matrix sum(Matrix A,int k){//A+A^2+A^3+…+A^k
    if(k==1)
        return A;
    if(k%2){
        Matrix temp=sum(A,k-1);
        Matrix pow=quickPow(A,k);
        return add(temp,pow);
    }
    else {
        Matrix temp=sum(A,k>>1);
        Matrix pow=add(quickPow(A,k>>1),E);
        return mul(temp,pow);
    }
}

【经典问题:共轭矩阵的构造】

1.问题

对于给出的 a、b、m、n,当满足 (a-1)^2<b<a^2 时,求:S_n=[(a+\sqrt b)^n]\:mod\:\:m

2.思路

设 A_n=(a+\sqrt b)^n,配项 B_n=(a-\sqrt b)^n,并令 C_n=A_n+B_n

由于 An、Bn 恰好共轭,因此 An、Bn 的和与积均为有理数

根据 (a-1)^2<b<a^2 ,可知 Bn<1

因此 C_n=[A_n],那么 S_n=[(a+\sqrt b)^n]\:mod\:\:m=[A_n]\:mod\:\:m=C_n\:mod \:\:m

故而可根据 Cn 来构造共轭矩阵,进行矩阵快速幂来求 Sn

3.共轭式的构造

根据 C_n=A_n+B_n=(a+\sqrt b)^n+(a-\sqrt b)^n 构造共轭矩阵

对 Cn 两端同乘 [(a+\sqrt b)+(a-\sqrt b)],有:C_n[(a+\sqrt b)+(a-\sqrt b)]=[(a+\sqrt b)^n+(a-\sqrt b)^n][(a+\sqrt b)+(a-\sqrt b)]

进行化简:

2aC_n=[(a+\sqrt b)^{n+1}+(a+\sqrt b)^n(a-\sqrt b)+(a-\sqrt b)^n(a+\sqrt b)+(a-\sqrt b)^{n+1}]

2aC_n=C_{n+1}+(a+\sqrt b)^n(a-\sqrt b)+(a-\sqrt b)^n(a+\sqrt b)

2aC_n=C_{n+1}+(a+\sqrt b)^{n-1}(a+\sqrt b)(a-\sqrt b)+(a-\sqrt b)^{n-1}(a-\sqrt b)(a+\sqrt b)

2aC_n=C_{n+1}+(a-\sqrt b)(a+\sqrt b)((a+\sqrt b)^{n-1}+(a-\sqrt b)^{n-1})

2aC_n=C_{n+1}+(a^2-b)C_{n-1}

写成矩阵形式:\begin{bmatrix}C_{n+1} \\ C_n \end{bmatrix} = \begin{bmatrix}2a&-(a^2-b) \\ 1&0 \end{bmatrix} \begin{bmatrix}C_n \\ C_{n-1} \end{bmatrix}

再递推一步:\begin{bmatrix}C_{n} \\ C_{n-1} \end{bmatrix} = \begin{bmatrix}2a&-(a^2-b) \\ 1&0 \end{bmatrix}^{n-1} \begin{bmatrix}C_1 \\ C_0 \end{bmatrix}

其中,\left\{\begin{matrix}C_0=2 \\C_1=(a+\sqrt b)^1+(a-\sqrt b)^{1}=2a \end{matrix}\right.

然后根据构造的矩阵进行矩阵快速幂计算结果即可

【例题】

  1. Fast Matrix Calculation(HDU-4965)(矩阵化简)点击这里
  2. So Easy!(HDU - 4565)(共轭矩阵的构造)点击这里
  3. Partial Sums(CF-223B)(1*n 的矩阵快速幂)点击这里
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值