P1939【模板】矩阵加速(数列)
P1939【模板】矩阵加速(数列)
难受就难受在a[i-3],这样的话让k=3就好了。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<cstring> 9 #define mod 1000000007 10 #define For(i,a,b) for(register long long i=a;i<=b;i++) 11 #define p(a) putchar(a) 12 #define g() getchar() 13 //by war 14 //2017.10.26 15 using namespace std; 16 long long k,t; 17 18 struct matrix 19 { 20 long long a[5]; 21 long long b[5][5]; 22 matrix operator *(const matrix&c)const 23 { 24 matrix r; 25 For(i,1,3) 26 For(j,1,3) 27 { 28 r.b[i][j]=0; 29 For(k,1,3) 30 r.b[i][j]=(r.b[i][j]+(b[i][k]*c.b[k][j])%mod)%mod; 31 } 32 return r; 33 } 34 }a; 35 36 void in(long long &x) 37 { 38 long long y=1; 39 char c=g();x=0; 40 while(c<'0'||c>'9') 41 { 42 if(c=='-') 43 y=-1; 44 c=g(); 45 } 46 while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); 47 x*=y; 48 } 49 void o(long long x) 50 { 51 if(x<0) 52 { 53 p('-'); 54 x=-x; 55 } 56 if(x>9)o(x/10); 57 p(x%10+'0'); 58 } 59 60 matrix ksm(matrix a,long long b) 61 { 62 matrix r=a;b--; 63 if(b==0) 64 return r; 65 while(b%2==0) 66 { 67 a=a*a; 68 b>>=1; 69 } 70 while(b>0) 71 { 72 if(b%2==1) 73 r=r*a; 74 a=a*a; 75 b>>=1; 76 } 77 return r; 78 } 79 80 int main() 81 { 82 in(t); 83 while(t--) 84 { 85 in(k); 86 if(k==1||k==2||k==3) 87 { 88 o(1),p('\n'); 89 90 } 91 else 92 { 93 a.a[1]=1; 94 a.a[2]=1; 95 a.a[3]=1; 96 a.b[1][1]=0; 97 a.b[1][2]=0; 98 a.b[1][3]=1; 99 a.b[2][1]=1; 100 a.b[2][2]=0; 101 a.b[2][3]=0; 102 a.b[3][1]=0; 103 a.b[3][2]=1; 104 a.b[3][3]=1; 105 matrix r,ans; 106 r=ksm(a,k-3); 107 for(register int i=1;i<=3;i++) 108 For(j,1,3) 109 { 110 ans.a[i]=0; 111 For(k,1,3) 112 ans.a[i]=(ans.a[i]+(a.a[i]*r.b[k][j])%mod)%mod; 113 } 114 For(i,3,3) 115 o((ans.a[i]%mod+mod)%mod),p('\n'); 116 } 117 118 } 119 return 0; 120 }