P1939 【模板】矩阵加速(数列)

题目描述

已知一个数列 aa,它满足:

a_x= \begin{cases} 1 & x \in\{1,2,3\}\\ a_{x-1}+a_{x-3} & x \geq 4 \end{cases}ax={1ax1+ax3x{1,2,3}x4

求 aa 数列的第 nn 项对 10^9+7109+7 取余的值。

输入格式

第一行一个整数 TT,表示询问个数。

以下 TT 行,每行一个正整数 nn。

输出格式

每行输出一个非负整数表示答案。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
typedef long long ll;
const int mod=1e9+7;
int t,n;
struct matrix {
    ll m[5][5];
}ans,base;
void init () {
    memset(ans.m,0,sizeof(ans.m));
    for (int i=1;i<=3;i++) ans.m[i][i]=1;
    memset(base.m,0,sizeof(base.m)); 
    base.m[1][1]=1;
    base.m[1][3]=1;
    base.m[2][1]=1;
    base.m[3][2]=1; 
} 
matrix mul (matrix a,matrix b) {
    matrix wjm;
    memset(wjm.m,0,sizeof(wjm.m));
    for (int i=1;i<=3;i++)
        for (int j=1;j<=3;j++)
            for (int k=1;k<=3;k++) {
                wjm.m[i][j]=wjm.m[i][j]+(a.m[i][k]%mod)*(b.m[k][j])%mod;
                wjm.m[i][j]%=mod; 
            }
    return wjm;
}
void qpow (int p) {
    while (p) {
        if (p&1) ans=mul(ans,base);
        base=mul(base,base);
        p>>=1;
    }
}
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d",&n);
        if (n<=3) {
            printf("1\n");
            continue;
        }
        init();
        qpow(n);
        printf("%lld\n",ans.m[2][1]);
    }
}

 

posted @ 2020-08-19 21:25  zlc0405  阅读(138)  评论(0编辑  收藏  举报