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 }