牛客挑战赛32 斐波那契数列卷积-矩阵快速幂

题目链接:https://ac.nowcoder.com/acm/problem/52937
题目大意:

牛客挑战赛32 斐波那契数列卷积-矩阵快速幂_第1张图片
牛客挑战赛32 斐波那契数列卷积-矩阵快速幂_第2张图片
推导:
牛客挑战赛32 斐波那契数列卷积-矩阵快速幂_第3张图片

#include 
#define LL long long
using namespace std;
const LL mod=998244353;

struct mat
{
     
    LL m[4][4];
};

mat msub(mat a, mat b, LL n)
{
     
    mat ret;
    memset(&ret,0,sizeof(ret));
    for(LL i=0;i<n;i++)
        for(LL k=0;k<n;k++)
        {
     
            if(a.m[i][k]==0){
     
                continue;
            }
            for(LL j=0;j<n;j++){
     
                ret.m[i][j]=(a.m[i][k]*b.m[k][j]%mod+ret.m[i][j])%mod;
            }
        }

    return ret;

}

void unit(mat &a, LL n){
     
    for(LL i=0 ;i<n; i++){
     
        a.m[i][i]=1;
    }
}

mat qpow(mat a,LL x, LL n)//快速幂
{
     
    mat ans;
    memset(&ans, 0, sizeof(ans));
    unit(ans, n);//初始化
    while(x){
     
        if(x&1) ans=msub(ans,a, n);
        a=msub(a,a, n);
        x>>=1;
    }
    return ans;
}

int main()
{
     
    LL n;
    scanf("%lld", &n);
    mat A={
     
        1, 1, 1, 0,
        1, 0, 0, 0,
        0, 0, 1, 1,
        0, 0, 1, 0
    };
    if(n==1){
     
        printf("0\n");
    }
    else if(n==2){
     
        printf("1\n");
    }
    else{
     

        mat t=qpow(A, n-2, 4);
        LL s=(t.m[0][0]+t.m[0][2]+t.m[0][3])%mod;
        printf("%lld\n", s);
    }

    return 0;
}

你可能感兴趣的:(矩阵快速幂)