【数论】 快速幂&&矩阵快速幂

首先复习快速幂

#include<bits/stdc++.h>
using namespace std;
long long power(long long a,long long b,long long k)
{
    long long ans=1,base=a;
    while (b>0)
    {
        if(b&1)    
        {
            ans*=base;
            ans%=k;
        }
        base*=base;
        base%=k;
        b>>=1;
    }
    return ans;
}
int main()
{
    long long b,p,k;
    cin>>b>>p>>k;
    cout<<b<<'^'<<p<<" mod "<<k<<"="<<(power(b,p,k) % k);
    return 0;
} 

我居然不DEFINE LL?可以看到上面的码十分好懂

那么矩阵快速幂也是一样的 只不过把*换成了mul函数



用计算机模拟矩阵乘法是这样的

struct mat{
    long long  m[100][100];//这里不开ll会死人
};

 

mat mul(mat x,mat y){
    mat r;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            r.m[i][j] = 0;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                r.m[i][j] += (x.m[i][k] * y.m[k][j]) % p;
                r.m[i][j] %= p;
            }
        }
    }
    return r;
}

首先定义一个矩阵并赋初值0 然后模拟乘的过程

什么?你想看矩阵乘法的公式?我不会MARKDOWN啊百度麻烦您了

还有一个小问题 就是在矩阵乘法中 什么矩阵是“1"?

答案就是(1,1)(2,2)(3,3).....(N,N)=1 其他地方为0的矩阵(可以自己手动模拟一下)

好了上完整代码

#include<bits/stdc++.h>
#define ll long long
#define p 1000000007

using namespace std;

struct mat{
    long long  m[100][100];
}e,ans1,ans2;

ll k,n;

mat mul(mat x,mat y){
    mat r;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            r.m[i][j] = 0;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                r.m[i][j] += (x.m[i][k] * y.m[k][j]) % p;
                r.m[i][j] %= p;
            }
        }
    }
    return r;
}

mat pow(mat x,ll y){
    mat ans = e;
    while (y>0){
        if(y&1){
            ans = mul(ans,x);
        }
        x=mul(x,x);
        y>>=1;
    }
    return ans;
}

int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) e.m[i][i] = 1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&ans1.m[i][j]);
        }
    }
    ans2 =pow (ans1,k); 
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%d ",ans2.m[i][j]);
        }
        cout<<endl;
    }
    return 0;
}

你会了这个才会矩阵加速之类乱七八糟的东西

TAG:SIN_XIII ⑨

转载于:https://www.cnblogs.com/SINXIII/p/10542294.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值