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

75 篇文章 0 订阅
39 篇文章 0 订阅

题目描述
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;

/*
0 1 0
0 0 1
1 0 1  该矩阵自乘n-4遍  最后  乘以矩阵 1 
                                       1
                                       1

*/ 
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define Mod 1000000007
#define LL long long
LL A[4][4],B[4][4],C[4][4];
int T,n;
void Mul(LL a[4][4],LL b[4][4]){
    LL c[4][4];
    memset(c,0,sizeof c );
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
            for(int k=1;k<=3;k++)
                c[i][j]=(c[i][j]+a[i][k]*b[k][j])%Mod;
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
            a[i][j]=c[i][j];
}
int main(){
    scanf("%d",&T);
    while(T--){
        memset(A,0,sizeof A );memset(B,0,sizeof B );
        memset(C,0,sizeof C );
        A[1][2]=1;A[2][3]=1;A[3][1]=1;A[3][3]=1;
        C[1][2]=1;C[2][3]=1;C[3][1]=1;C[3][3]=1;
        B[1][1]=1;B[2][1]=1;B[3][1]=1;
        scanf("%d",&n);
        if(n<=3){ printf("1\n");continue; }
        n-=3;n--;//n-- 是因为 刚开始让C=A了 
        while(n){
            if(n&1) Mul(C,A);
            Mul(A,A); n>>=1;
        }
        LL D[4][4];
        memset(D,0,sizeof D );
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                for(int k=1;k<=3;k++)
                    D[i][j]=(D[i][j]+C[i][k]*B[k][j])%Mod;
        printf("%lld\n",D[3][1]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值