矩阵快速幂(模板)(求通项公式的第几项通常用其求解)

题目:有规律的斐波那契
求通项公式的第几项通常用矩阵快速幂求解

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const mod=998244353;
struct L{
    ll a[3][3];
    void init(int f=0){     //默认参数为0
        memset(a,0,sizeof a);
        if(f==1){   //将其初始化为单位矩阵
            this->a[0][0]=this->a[1][1]=this->a[2][2]=1;
        }
        if(f==2){   //将其初始化为构造矩阵
            this->a[0][0]=this->a[0][1]=
            this->a[0][2]=this->a[1][0]=
            this->a[2][1]=1;
        }
        if(f==3){   //将其初始化为含斐波那契矩阵  //即通项公式最初的样子
            this->a[0][0]=2;
            this->a[1][0]=this->a[2][0]=1;
        }
    }
    L operator*(L const &b){
        L res;
        res.init();
        for(int i=0;i<3;++i){
            for(int j=0;j<3;++j){
                for(int k=0;k<3;++k){
                    res.a[i][j]=(res.a[i][j]+this->a[i][k]*b.a[k][j]%mod)%mod;  //a[i][k]*b[k][j] 表示第i行第k个乘第j列第k个 //多维矩阵相乘也是这一句代码    //这里当心出错 
                }
            }
        }
        return res;
    }
};
L ksm(L a,ll b){     
    L res;res.init(1);
    while(b){
        if(b&1){  //快速幂是按位的多少运算(将b看成二进制),所以最多执行64次
            res=res*a;
        }
        a=a*a;
        b >>= 1;
    }
    return res; 
}
ll t,x;
int main(){
    cin >> t;
    L m1,m2;
    while(t--){
        cin >> x;
        m2.init(3);
        if(x<3) cout << m2.a[2-x][0] << "\n";
        else {
            m1.init(2); 
            cout << (ksm(m1,x-2)*m2).a[0][0] << "\n";
        } 
    }
    return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务