洛谷1939 【模板】矩阵加速(数列)

(http://www.elijahqi.win/2017/07/09/%E6%B4%9B%E8%B0%B71939-%E3%80%90%E6%A8%A1%E6%9D%BF%E3%80%91%E7%9F%A9%E9%98%B5%E5%8A%A0%E9%80%9F%EF%BC%88%E6%95%B0%E5%88%97%EF%BC%89/)
题目描述

a[1]=a[2]=a[3]=1

a[x]=a[x-3]+a[x-1] (x>3)

求a数列的第n项对1000000007(10^9+7)取余的值。

输入输出格式

输入格式:

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

以下T行,每行一个正整数n。

输出格式:

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

输入输出样例

输入样例#1:

3
6
8
10
输出样例#1:

4
9
19
说明

对于30%的数据 n<=100;

对于60%的数据 n<=2*10^7;

对于100%的数据 T<=100,n<=2*10^9;

#include<cstdio>
#include<cstring>
#define P 1000000007
inline int read(){
    int x=0;char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
    return x;
}
int T;
struct matrix{
    int f[5][5],l,c;
}base,base1;
inline matrix multiply(matrix a,matrix b){
    matrix c;memset(c.f,0,sizeof(c.f));
    c.l=a.l;c.c=b.c;
    for (int i=1;i<=c.l;++i){
        for (int j=1;j<=c.c;++j){
            for (int z=1;z<=a.c;++z){
                (c.f[i][j]+=(long long)a.f[i][z]*b.f[z][j]%P)%=P;
            }
        }
    }
    return c;
}
void build(){
    memset(base.f,0,sizeof(base.f));base.l=base.c=3;
    base.f[2][1]=1;base.f[3][2]=1;base.f[1][3]=1;base.f[3][3]=1;
    memset(base1.f,0,sizeof(base.f));
    base1.f[1][1]=1;base1.f[1][2]=1;base1.f[1][3]=1;
    base1.l=1;base1.c=3;
}
int main(){
    //freopen("1939.in","r",stdin);
    //freopen("1939.out","w",stdout);
    T=read();
    while (T--){
        build();
        int tmp=read();
        if (tmp<=3) {printf("1\n");continue;}
        tmp-=3;
        for (;tmp!=0;tmp>>=1,base=multiply(base,base)){
            if (tmp&1) base1=multiply(base1,base);
        }
        printf("%d\n",base1.f[1][3]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值