矩阵快速幂 模板

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=110;
const int  mod=1e9+7;
//#define Mod(x) ((x)%mod)
typedef long long ll;
struct node
{
    int a[maxn][maxn];
} unit;//单位矩阵
ll Mod(ll sum)
{
    return sum%(ll)mod;
}
node Init(node a)//初始化一个矩阵为单位矩阵
{
    for(int i=0; i<maxn; i++)
        for(int j=0; j<maxn; j++)
            if(i==j)
                a.a[i][j]=1;
            else
                a.a[i][j]=0;
    return a;
}
node Mult(int n,node q,node p)//矩阵乘法 也可重载 "*" 运算符
{
    node t;
    ll x;
    for(int i=0; i<n; i++)
    for(int  j=0; j<n; j++)
    {
         x=0;
        for(int k=0; k<n; k++)
        {
            x+=Mod((ll)q.a[i][k]*p.a[k][j]);
        }
        t.a[i][j]=Mod(x);
    }


    return t;
}
node Pow(int n,int m,node a)//快速幂的基本操作
{
    node ret=unit;
    while(m!=0)
    {
        if(m&1)
            ret=Mult(n,ret,a);
        a=Mult(n,a,a);
        m=m>>1;


    }
    return ret;
}
//10的2进制为1010 10=2^1+2^3; a^10=a^(2^3)*a^(2^1) 有没有发现前一个始终是后一个的a^x倍 于是每一次计算完a过后执行a*a操作 
//然后每次分解10的2进制为如果是1也就是&1为真的话执行就把结果乘起来。
int main()
{
    int n,m;
    cin>>n>>m;
    node a;
    unit=Init(unit);
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            cin>>a.a[i][j];
    a=Pow(n,m,a);
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(j==n-1)
                printf("%d\n",a.a[i][j]);
            else
                printf("%d ",a.a[i][j]);
        }
    }
    return 0;
}
阅读更多

没有更多推荐了,返回首页