Recursive sequence HDU - 5950 (矩阵加速线性递推+矩阵快速幂)

矩阵加速的线形递推的裸题,难点就在于构造矩阵。


代码:

using namespace std;
const int MAXN=7;
int T;
ll a,b,n;
typedef struct{
    ll mp[MAXN][MAXN];
    void init(){
        mem(mp,0);
        for(int i=0;i<MAXN;i++){
             mp[i][i]=1;
         }
    }
}matrix;
matrix pp={
    1,1,0,0,0,0,0,
    2,0,0,0,0,0,0,
    1,0,1,0,0,0,0,
    4,0,4,1,0,0,0,
    6,0,6,3,1,0,0,
    4,0,4,3,2,1,0,
    1,0,1,1,1,1,1
};
matrix multi(matrix a,matrix b)
{
    matrix res;
    for(int i=0;i<MAXN;i++){
       for(int j=0;j<MAXN;j++){
           res.mp[i][j]=0;
           for(int k=0;k<MAXN;k++){
               res.mp[i][j]+=(a.mp[i][k]*b.mp[k][j])%MOD;
               res.mp[i][j]=res.mp[i][j]%MOD;
           }
       }
    }
    return res;
}
matrix fastm(matrix a,ll x)
{
    matrix res;
    res.init();
    while(x){
        if(x&1){
            res=multi(res,a);
        }
        x>>=1;
        a=multi(a,a);
    }
    return res;
}
int main()
{
    cin>>T;
    while(T--){
        scanf("%lld%lld%lld",&n,&a,&b);
        if(n==1){
            printf("%lld\n",a);
        }else if(n==2){
            printf("%lld\n",b);
        }else{
            matrix now=fastm(pp,n-2);
            ll num;
            num=(b*now.mp[0][0])%MOD;
            num=(num+a*now.mp[1][0]%MOD)%MOD;
            num=(num+16*now.mp[2][0]%MOD)%MOD;
            num=(num+8*now.mp[3][0]%MOD)%MOD;
            num=(num+4*now.mp[4][0]%MOD)%MOD;
            num=(num+2*now.mp[5][0]%MOD)%MOD;
            num=(num+now.mp[6][0]%MOD)%MOD;
            printf("%lld\n",num);
        }
    }

    return 0;
}

posted @ 2020-09-10 16:38  hachuochuo  阅读(126)  评论(0编辑  收藏  举报