P1962 斐波那契数列

P1962 斐波那契数列
矩阵加速

  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 inf long long_MAX
 11 #define For(i,a,b) for(register long long i=a;i<=b;i++)
 12 #define p(a) putchar(a)
 13 #define g() getchar()
 14 //by war
 15 //2017.10.26
 16 using namespace std;
 17 long long k;
 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,2)
 26           For(j,1,2)
 27           {
 28              r.b[i][j]=0;
 29              For(k,1,2)
 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(k);
 83     if(k==1||k==2)
 84     {
 85         o(1);
 86         exit(0);
 87     }
 88     a.a[1]=1;
 89     a.a[2]=1;
 90     a.b[1][1]=0;
 91     a.b[1][2]=1;
 92     a.b[2][1]=1;
 93     a.b[2][2]=1;
 94     matrix r,ans;
 95     r=ksm(a,k-2);
 96     For(i,1,2)
 97           For(j,1,2)
 98           {
 99              ans.a[i]=0;
100              For(k,1,2)
101             ans.a[i]=(ans.a[i]+(a.a[i]*r.b[k][j])%mod)%mod;
102           }
103     For(i,2,2)
104     o((ans.a[i]%mod+mod)%mod);
105      return 0;
106 }

 

posted @ 2017-10-26 17:02  WeiAR  阅读(195)  评论(0编辑  收藏  举报