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

题目描述

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>
#include<iostream>
#include<algorithm>
#define mod 1000000007
using namespace std;
int T,n;
long long ans[3][3],t[3][3],r[3][3];
void mul(long long a[3][3],long long b[3][3]){
    memset(r,0,sizeof(r));
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<3;k++)
                r[i][j]+=a[i][k]*b[k][j],r[i][j]%=mod;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            a[i][j]=r[i][j];
}
int main(){
    scanf("%d",&T);
    while(T--){
        memset(t,0,sizeof(t));
        memset(ans,0,sizeof(ans));
        scanf("%d",&n);
        t[0][0]=1;t[0][1]=1;
        t[1][2]=1;t[2][0]=1;
        ans[0][0]=1;ans[0][1]=1;ans[0][2]=1;
        if(n==1||n==2||n==3){ cout<<"1"<<endl;continue; }
        n-=3;
        for(;n;n>>=1){
            if(n&1)    mul(ans,t);
            mul(t,t);
        }
        cout<<ans[0][0]<<endl;
    }
}

 

posted @ 2017-11-07 14:30  一蓑烟雨任生平  阅读(147)  评论(0编辑  收藏  举报