模板 - 数学 - 矩阵快速幂

线性递推公式找递推矩阵的方法:

https://blog.csdn.net/synapse7/article/details/18790165

快速幂

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define MAXN 105


class Matrix {
public:
     long long m[MAXN][MAXN];
//二维数组存放矩阵
    Matrix(){
        memset(m,0,sizeof(m));
    }
    //对数组的初始化
    void init(long long  num[MAXN][MAXN]){
        for(int i = 0 ; i < MAXN ; i++){
            for(int j = 0 ; j < MAXN ; j++){
                m[i][j] = num[i][j];
           }
       }
    }
    //重载矩阵的乘法运算

    friend Matrix operator*(Matrix &m1 ,Matrix &m2) {
        int i, j, k;
        Matrix temp;
        for (i = 0; i < MAXN; i++) {
            for (j = 0; j < MAXN; j++) {
                temp.m[i][j] = 0;
                for(k = 0 ; k < MAXN ; k++)
                   temp.m[i][j] += (m1.m[i][k] * m2.m[k][j])%mod;
                temp.m[i][j] %= mod;
//注意每一步都进行取模
           }
        }
        return temp;
    }
    //矩阵的快速幂

    friend Matrix quickpow(Matrix &M , long long n){
        Matrix tempans;
//初始化为单位矩阵
        //初始化
        for(int i = 0 ; i < MAXN ; i++){
            for(int j = 0 ; j < MAXN ; j++){
                if(i == j)
                    tempans.m[i][j] = 1;
                else
                    tempans.m[i][j] = 0;
            }
        }
        //快速幂(类似整数)
        while(n){
            if(n & 1)
                tempans = tempans * M;
//已经重载了*
            n = n >> 1;
            M = M * M;
            //cout<<n<<endl;
        }
       return tempans;
    }

    show(){
        /*for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                cout<<m[i][j]<<" ";
            }
            cout<<endl;
        }
        cout<<endl;*/
    }
};

int main() {
    Matrix A , ans;
    long long T , n , k , sum;
//数据类型为long long
    long long num[MAXN][MAXN];
//输入的数据存入数组

    ll N,M;
    scanf("%lld%d",&N,&M);
    k=N-M;

    n=M;

    memset(num , 0 , sizeof(num));
    for(int i = 0 ; i < n-1 ; i++){
        num[i][i+1]=1;
    }

    num[n-1][0]=1;
    num[n-1][n-1]=1;

    A.init(num);//初始化A矩阵

    A.show();
    Matrix ini;

    for(int i=0;i<M-1;i++){
        ini.m[i][0]=1;
    }

    ini.m[M-1][0]=2;

    if(N<M){
        cout<<"1"<<endl;
        return 0;
    }
    ans = quickpow(A , k);//求出矩阵的快速幂

    ans.show();



    ini.show();
    Matrix res=ans*ini;

    res.show();

    ll R=res.m[M-1][0];
    cout<<(R%mod)<<endl;

}

猜你喜欢

转载自www.cnblogs.com/Yinku/p/10398954.html
今日推荐