WHYZOJ-#14 数列(矩阵快速幂)

题目描述

a[1]=a[2]=a[3]=1a[1]=a[2]=a[3]=1

a[x]=a[x3]+a[x1](x>3)a[x]=a[x−3]+a[x−1](x>3)

aa数列的第nn项对10000000071000000007(109+7109+7)取余的值。

输入描述 第一行一个整数TT,表示询问个数。

以下TT行,每行一个正整数nn。

输出描述

每行输出一个非负整数表示答案。

样例输入

3
6
8
10

样例输出

4
9
19

时间限制、数据范围及描述

时间:1s 空间:256M

对于30%30%的数据 n100n≤100;

对于60%60%的数据 n2107n≤2∗107;

对于100%100%的数据 T100T≤100,n2109n≤2∗109;

除了那个优化的小技巧,劳资的矩阵快速幂一点都没忘,结果踏马还搞了半天才搞好

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int mod=1000000007;
 5 int t;
 6 int n;
 7 struct Mat{
 8     int x,y;
 9     LL mat[5][5];
10     Mat(){x=y=0;memset(mat,0,sizeof(mat));}
11     Mat operator *(const Mat &tt) {
12         int i,j,k;
13         Mat an;
14         an.x=x,an.y=tt.y;
15         for (k=1;k<=y;k++){
16             for (i=1;i<=an.x;i++){
17                 if (mat[i][k]){
18                     for (j=1;j<=an.y;j++){
19                         an.mat[i][j]=(an.mat[i][j]+mat[i][k]*tt.mat[k][j])%mod;
20                     }
21                 }
22             }
23         }
24         return an;
25     }
26 };
27 Mat ksm(Mat tt,int x){
28     int i,j;
29     Mat an;
30     an.x=an.y=3;
31     an.mat[1][1]=an.mat[2][2]=an.mat[3][3]=1;
32     while (x){
33         if (x%2) an=tt*an;//注意:不能写成an*tt 
34         tt=tt*tt;
35         x/=2;
36     }
37     return an;
38 }
39 int main(){
40     freopen ("string.in","r",stdin);
41     freopen ("string.out","w",stdout);
42     int i,j;
43     scanf("%d",&t);
44     while (t--){
45         scanf("%d",&n);
46         if (n<=3) {puts("1");continue;}
47         int x=(n-1)/3+1,y=n%3;y=(y==0?3:y);
48         Mat ans,mm,nn;
49         mm.x=mm.y=3;
50         mm.mat[1][1]=mm.mat[1][3]=mm.mat[2][1]=mm.mat[2][2]=mm.mat[2][3]=mm.mat[3][1]=mm.mat[3][2]=1;
51         mm.mat[3][3]=2;
52         nn.x=3,nn.y=1;
53         nn.mat[1][1]=nn.mat[2][1]=nn.mat[3][1]=1;
54         ans=ksm(mm,x-1)*nn;//注意,理由同上 
55         printf("%lld
",ans.mat[y][1]);
56     }
57     return 0;
58 }
未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
原文地址:https://www.cnblogs.com/keximeiruguo/p/7346251.html