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 }

 

posted @ 2017-10-26 20:15  WeiAR  阅读(239)  评论(0编辑  收藏  举报