矩阵快速幂模板(持续更新)

来源:互联网 发布:手机熊猫登录网络 编辑:程序博客网 时间:2024/05/28 09:32

经过几次比较,目前总结封装矩阵的模板

加上优化,用这个代码可以0MS过杭电上的一道题(以后可能还有更快的)

typedef long long ll;const int MAXN = 10;long long mod;struct Matrix{    long long mat[MAXN][MAXN];    void Zero(){        memset(mat, 0, sizeof(mat));    }    void Unit(){        memset(mat, 0, sizeof(mat));        for (int i = 0; i < MAXN; i++)            mat[i][i] = 1;    }    void output(){        for (int i = 0; i < MAXN; i++){            for (int j = 0; j < MAXN; j++){                printf("%d ", mat[i][j]);            }            printf("\n");        }    }};Matrix operator*(Matrix &a, Matrix &b){    Matrix tmp;    tmp.Zero();///初始化    for (int k = 0; k < MAXN; k++){        for (int i = 0; i < MAXN; i++){            if (!a.mat[i][k])                continue;            for (int j = 0; j < MAXN; j++){                tmp.mat[i][j] += a.mat[i][k] * b.mat[k][j] % mod;                if ( tmp.mat[i][j] >= mod)                    tmp.mat[i][j] -= mod;            }        }    }    return tmp;}Matrix operator ^(Matrix a, int k){    Matrix tmp;///单位矩阵    tmp.Unit();    if(k<=1)        return a;    for (; k; k >>= 1){        if (k & 1)            tmp = tmp * a;        a = a * a;    }    return tmp;}

模板应用:

传送门:http://acm.split.hdu.edu.cn/showproblem.php?pid=4990

代码:(0MS)

#include<iostream>#include<sstream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<ctime>#include<list>#include<vector>#include<set>#include<map>#include<stack>#include<queue>#pragma GCC optimize("02")#define cl(a,b) memset(a,b,sizeof(a))#define in freopen("F://1.txt","r",stdin)#define out freopen("F://2.txt","w",stdout)using namespace std;typedef unsigned long long llu;typedef long long ll;const ll inf=(ll)1<<60;const int maxn=1e4+7;const int MAXN = 10;ll mod;struct Matrix{    ll mat[MAXN][MAXN];    void Zero(){        //memset(mat, 0, sizeof(mat));        cl(mat,0);    }    void Unit(){        //memset(mat, 0, sizeof(mat));        cl(mat,0);        for (int i = 0; i < MAXN; i++)            mat[i][i] = 1;    }    void output(){        for (int i = 0; i < MAXN; i++){            for (int j = 0; j < MAXN; j++){                printf("%lld ", mat[i][j]);            }            printf("\n");        }    }};Matrix operator*(Matrix &a, Matrix &b){    Matrix tmp;    tmp.Zero();///初始化    for (int k = 0; k < MAXN; k++){        for (int i = 0; i < MAXN; i++){            if (!a.mat[i][k])                continue;            for (int j = 0; j < MAXN; j++){                tmp.mat[i][j] += a.mat[i][k] * b.mat[k][j] % mod;                if ( tmp.mat[i][j] >= mod)                    tmp.mat[i][j] -= mod;            }        }    }    return tmp;}Matrix operator ^(Matrix a, int k){    Matrix tmp;///单位矩阵    tmp.Unit();    if(k<=1)        return a;    for (; k; k >>= 1){        if (k & 1)            tmp = tmp * a;        a = a * a;    }    return tmp;}int main(){    Matrix mt;    mt.Zero();    mt.mat[0][0] = 1;    mt.mat[0][1] = 1;    mt.mat[1][0] = 2;    mt.mat[2][0] = 1;    mt.mat[2][2] = 1;    Matrix mt2;    mt2.Zero();    mt2.mat[0][0] = 2;    mt2.mat[0][1] = 1;    mt2.mat[0][2] = 1;    ll n,m;    while(~scanf("%lld%lld", &n, &m)){        mod=m;        if(n==1){            printf("%lld\n", 1%m);            continue;        }        else if(n==2){            printf("%lld\n", 2%m);            continue;        }        Matrix m3;        m3 = mt ^ (n-2);        Matrix ans = mt2 * m3;        printf("%lld\n", ans.mat[0][0]);    }    return 0;}