矩阵乘法快速幂 codevs 1732 Fibonacci数列 2

1732 Fibonacci数列 2

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
题目描述 Description

在“1250 Fibonacci数列”中,我们求出了第n个Fibonacci数列的值。但是1250中,n<=109。现在,你的任务仍然是求出第n个Fibonacci数列的值,但是注意:n为整数,且1 <= n <= 100000000000000

输入描述 Input Description

输入有多组数据,每组数据占一行,为一个整数n(1 <= n <= 100000000000000)

输出描述 Output Description

输出若干行。每行输出第(对应的输入的)n个Fibonacci数(考虑到数会很大,mod 1000000007)

样例输入 Sample Input

3
4
5

样例输出 Sample Output

2
3
5

数据范围及提示 Data Size & Hint

1 <= n <= 100000000000000

数据虽然大了,但是矩阵快速幂仍然可以解决,而且速度飞快,只要注意防止longlong 相乘溢出即可

 1 #define N 3
 2 #define ll long long
 3 #include<iostream>
 4 using namespace std;
 5 #include<cstdio>
 6 #include<cstring>
 7 struct Jz{
 8     int cal,line;
 9     long long jz[N][N];
10 };
11 long long q=1000000007;
12 int read()
13 {
14     char s;
15     int ans=0,ff=1;
16     s=getchar();
17     while(s<'0'||s>'9')
18     {
19         if(s=='-') ff=-1;
20         s=getchar();
21     }
22     while('0'<=s&&s<='9')
23     {
24         ans=ans*10+s-'0';
25         s=getchar();
26     }
27     return ans*ff;
28 }
29 long long quick_mod(ll a,ll b)/*慢乘法防止溢出*/
30 {
31     a%=q;b%=q;
32     ll ans=0;
33     while(b)
34     {
35         if(b&1)
36         {
37             ans+=a;
38             ans%=q;//
39         }
40         b>>=1;
41         a<<=1;
42         a%=q;
43     }
44     return ans;
45 }
46 Jz martax(Jz x,Jz y)
47 {
48     Jz ans;
49     ans.line=x.line;
50     ans.cal=y.cal;
51     for(int i=1;i<=ans.line;++i)
52       for(int j=1;j<=ans.cal;++j)
53       {
54           ans.jz[i][j]=0;
55           for(int k=1;k<=x.cal;++k)
56             ans.jz[i][j]=(ans.jz[i][j]+quick_mod(x.jz[i][k],y.jz[k][j]))%q;
57       }
58     return ans;
59 }
60 long long Fast_martax(long long n)
61 {
62     if(n==1||n==2) return 1;
63     n-=2;
64     Jz ans,a;
65     a.cal=a.line=2;
66     a.jz[1][1]=0;a.jz[1][2]=1;
67     a.jz[2][1]=1;a.jz[2][2]=1;
68     ans.line=2;ans.cal=1;
69     ans.jz[1][1]=1;ans.jz[2][1]=1;
70     while(n)
71     {
72         if(n&1)
73         {
74             ans=martax(a,ans);
75         }
76         n>>=1;
77         a=martax(a,a);
78     }
79     return ans.jz[2][1]%q;
80 }
81 int main()
82 {
83     long long n;
84     while(scanf("%lld",&n)==1)
85     {
86         printf("%lld
",Fast_martax(n));
87     }
88     return 0;
89 }
原文地址:https://www.cnblogs.com/c1299401227/p/5552503.html