题目描述
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;
题解:
其实这篇本来想写日记的,但是老师突然来到了我的身边,我就迅速把这道刚做完的题粘到了这里。
有始有终,就写吧。
谁可以告诉我,为什么我的暴力没有分!
众人OS:你错了呗。

#include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int mod=1e9+7; int T, n; LL tmp[3][3]={{0,0,1},{1,0,0},{0,1,1}}; struct Matrix33{ LL mat[3][3]; Matrix33 operator *(Matrix33 b){ Matrix33 m; for (int i=0; i<3; ++i) for (int j=0; j<3; ++j){ m.mat[i][j]=0; for (int k=0; k<3; ++k) m.mat[i][j]=(m.mat[i][j]+(mat[i][k]*b.mat[k][j]%mod))%mod; } return m; } }beg, unit, plus; Matrix33 get_mat(int n){ memcpy(plus.mat, tmp, sizeof(tmp)); Matrix33 ans=unit; while (n){ if (n&1) ans=ans*plus; plus=plus*plus; n>>=1; } return ans; } int main(){ unit.mat[0][0]=unit.mat[1][1]=unit.mat[2][2]=1; beg.mat[0][0]=beg.mat[0][1]=beg.mat[0][2]=1; scanf("%d", &T); for (int tt=0; tt<T; ++tt){ scanf("%d", &n); if (n<4) printf("1 "); else printf("%lld ", (beg*get_mat(n-3)).mat[0][2]); } return 0; }
一世安宁