关于数论矩阵乘法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于数论矩阵乘法相关的知识,希望对你有一定的参考价值。

今天下午刷jingjing的矩乘题,搞得我肾虚。。按照现在所学,大概总结一下。
矩乘的运算是这样的,左边的第一行和右边的第一列乘积后加在答案的第一行第一列,由此类推。

Matrix matrix_cheng(Matrix a,Matrix b)
{
    Matrix c;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                c.mp[i][j]=(c.mp[i][j]+a.mp[i][k]*b.mp[k][j])%1000000007LL;
    return c;
}

一般矩阵乘法会和快速幂一起用,矩阵加速解决一些一维一边推,或者范围较小的二维一边推的DP题目,以及一些有循环节的题目。总之,就是根据不变的公式一般的规律,来利用快速幂加速。

建议学习的同学去做Matrix67: 十个利用矩阵乘法解决的经典题目,这里就不一一列举了。

给出一个矩乘快速幂的模板:

 

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
struct Matrix
{
    LL mp[20][20];
    Matrix()
    {
        memset(mp,0,sizeof(mp));
    }
}A,ans;
int n,k;
Matrix matrix_cheng(Matrix a,Matrix b)
{
    Matrix c;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                c.mp[i][j]=(c.mp[i][j]+a.mp[i][k]*b.mp[k][j])%1000000007LL;
    return c;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)scanf("%lld",&A.mp[i][j]);
        ans.mp[i][i]=1;
    }
    
    while(k!=0)
    {
        if(k%2==1)ans=matrix_cheng(ans,A);
        k/=2;A=matrix_cheng(A,A);
    }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<n;j++)printf("%lld ",ans.mp[i][j]);
        printf("%lld\n",ans.mp[i][n]);
    }
    return 0;
}

 

以上是关于关于数论矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4002[JLOI2015]有意义的字符串 数论+矩阵乘法

数论,关于求乘法逆元素

7月16日

数论--乘法逆元

数论学习之乘法逆元

HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)