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

 

Solution:

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

代码:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 //#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
 5 using namespace std;
 6 const int mod=9907;
 7 int t,n;
 8 il int gi()
 9 {
10     int a=0;char x=getchar();bool f=0;
11     while((x<'0'||x>'9')&&x!='-')x=getchar();
12     if(x=='-')x=getchar(),f=1;
13     while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
14     return f?-a:a;
15 }
16 struct mat{
17     int a[5][5],r,c;
18 };
19 il mat mul(mat x,mat y)
20 {
21     mat p;
22     memset(&p,0,sizeof(p));
23     for(int i=0;i<x.r;i++)
24         for(int j=0;j<y.c;j++)
25             for(int k=0;k<x.c;k++)
26     p.a[i][j]=(p.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
27     p.r=x.r;p.c=y.c;
28     return p;
29 }
30 il void fast(int k)
31 {
32     mat p,ans;
33     memset(&p,0,sizeof(p));
34     memset(&ans,0,sizeof(ans));
35     p.r=p.c=3;
36     p.a[0][1]=p.a[1][2]=p.a[2][0]=p.a[2][1]=1;
37     ans.r=ans.c=3;
38     ans.a[0][0]=ans.a[1][1]=ans.a[2][2]=1;
39     while(k){
40         if(k&1)ans=mul(p,ans);
41         p=mul(p,p);
42         k>>=1;
43     }
44     p.a[0][0]=1,p.a[1][0]=2,p.a[2][0]=3;
45     p.c=1;
46     ans=mul(ans,p);
47     printf("%d\n",(int)ans.a[2][0]);
48 }
49 int main()
50 {
51     t=gi();
52     while(t--){
53         n=gi();
54         if(n<4)printf("%d\n",n);
55         else fast(n-3);
56     }
57     return 0;
58 }

 

上一篇:linux系统安全审计简单设置


下一篇:实变函数例题(4)