矩阵快速幂模板+例题

相关知识学习往这边–》https://blog.csdn.net/wust_zzwh/article/details/52058209

搞懂了模板想怎么写就怎么写,看个人

整数快速幂模板:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

long long fastpow(int x,int n){

    long long ans = 1;
    long long base = x;

    while(n){

        if(n&1)
            ans *= base;
        base *= base;
        n >>= 1;
    }
    return ans;
}

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t;
    cin >> t;

    while(t--){

        int x,n;
        cin >> x >> n;

        cout << fastpow(x,n) << endl;

    }

    system("pause");
    return 0;
}

矩阵快速幂模板:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

const int maxn = 1010;

//原始矩阵,最终矩阵,临时矩阵
int x[maxn][maxn],ans[maxn][maxn],temp[maxn][maxn];

void maxtrix_mul(int a[][maxn],int b[][maxn],int n){    //矩阵乘法

    memset(temp,0,sizeof(temp));
    
    for(int i = 0; i<n; i++)
        for(int j = 0; j<n; j++)
            for(int k = 0; k<n;k++)
                temp[i][j] += a[i][k] * b[k][j];
    
    for(int i = 0;i<n;i++)
        for(int j = 0;j<n;j++)
            a[i][j] = temp[i][j];
}

void fast_pow(int x[][maxn],int k,int n){   //快速幂

    for(int i = 0; i<n; i++)
        for(int j = 0;j<n;j++)
            ans[i][j] = (i == j) ? 1 : 0;
    
    while(k){

        if(k&1) 
            maxtrix_mul(ans,x,n);
            
        maxtrix_mul(x,x,n);
        k >>= 1;
    }
}

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n,k;
    cin >> n >> k;
    
    for(int i = 0; i<n; i++)
        for(int j = 0; j<n; j++)
            cin >> x[i][j];

    fast_pow(x,k,n);

    for(int i = 0;i<n;i++){
        for(int j = 0;j<n;j++)
            cout << ans[i][j] << " ";        
        cout << endl;
    }

    system("pause");
    return 0;
}

下面这个题忘记给数组还原了,搞得我找半天没找到错误。。

POJ3070,斐波那契数列

AC代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

const int maxn = 1010;

//原始矩阵,最终矩阵,临时矩阵
int x[maxn][maxn],ans[maxn][maxn],temp[maxn][maxn];

void maxtrix_mul(int a[][maxn],int b[][maxn],int n){    //矩阵乘法

    memset(temp,0,sizeof(temp));
    
    for(int i = 0; i<n; i++)
        for(int j = 0; j<n; j++)
            for(int k = 0; k<n;k++)
                temp[i][j] += a[i][k] * b[k][j];
    
    for(int i = 0;i<n;i++)
        for(int j = 0;j<n;j++)
            a[i][j] = temp[i][j];
}

void fast_pow(int x[][maxn],int k,int n){   //快速幂

    for(int i = 0; i<n; i++)
        for(int j = 0;j<n;j++)
            ans[i][j] = (i == j) ? 1 : 0;
    
    while(k){

        if(k&1) 
            maxtrix_mul(ans,x,n);
            
        maxtrix_mul(x,x,n);
        k >>= 1;
    }
}

int main(){

    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n,k;
    cin >> n >> k;
    
    for(int i = 0; i<n; i++)
        for(int j = 0; j<n; j++)
            cin >> x[i][j];

    fast_pow(x,k,n);

    for(int i = 0;i<n;i++){
        for(int j = 0;j<n;j++)
            cout << ans[i][j] << " ";        
        cout << endl;
    }

    system("pause");
    return 0;
}

下面这个也是斐波那契数列,但是有点不一样。要找规律,还要开long long数据类型才可以。。。
HDU6198

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

#define mod 998244353
typedef long long ll;
struct Maxtrix{
    ll mat[2][2];
}base,ans,temp;

Maxtrix maxtrix_mul(Maxtrix a,Maxtrix b){

    memset(temp.mat,0,sizeof(temp.mat));

    for(int i = 0; i<2; i++)
        for(int j = 0; j<2; j++)
            for(int k = 0; k<2; k++)
                temp.mat[i][j] = (temp.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % mod;
    
    return temp;
}

void fast_pow(ll k){

    base.mat[0][0] = base.mat[0][1] = base.mat[1][0] = 1;
    base.mat[1][1] = 0;

    ans.mat[0][1] = ans.mat[1][0] = 0;
    ans.mat[0][0] = ans.mat[1][1] = 1;

    while(k){

        if(k&1) ans = maxtrix_mul(ans,base);
        base = maxtrix_mul(base,base);

        k >>= 1;
    }
}

int main(){

    ll n;
    while(scanf("%lld",&n) != EOF){

        fast_pow(2*n + 3);

        printf("%lld\n",ans.mat[0][1] - 1);
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值