您的位置:首页 > 其它

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

2018-03-09 23:00 716 查看
(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: