码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷P1962 斐波那契数列

时间:2017-11-07 00:13:29      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:rar   怎么办   omega   range   int   click   tor   while   main   

题目:https://www.luogu.org/problemnew/show/1962

题目背景

大家都知道,斐波那契数列是满足如下性质的一个数列:

• f(1) = 1

• f(2) = 1

• f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数)

题目描述

请你求出 f(n) mod 1000000007 的值。

输入输出格式

输入格式:

 

·第 1 行:一个整数 n

 

输出格式:

 

第 1 行: f(n) mod 1000000007 的值

 

输入输出样例

输入样例#1: 
5
输出样例#1: 
5
输入样例#2: 
10
输出样例#2: 
55

说明

对于 60% 的数据: n ≤ 92

对于 100% 的数据: n在long long(INT64)范围内。

 

解析

给了60分的暴力分,美滋滋= ̄ω ̄=

那么剩下的40分怎么办Σ( ° △ °|||)︴

别告诉我你要打一个辣么大的表( ﹁ ﹁ ) ~→

好吧,这就需要一个重要的知识点叫做矩阵乘法。

矩阵乘法不会的,请咨询度娘吧23333333333333.

矩阵乘法满足结合律哦。

我们可以把状态转移方程转化成矩阵相乘,然后,

中间乘的矩阵都是一样的哦。

那么,想到什么了吗(⊙ω⊙)

对啦,就是快速幂啦(∩_∩)

矩阵快速幂与快速幂的做法很相似哦!相信大佬们一定会的(~ ̄▽ ̄)~

好了,蒟蒻的代码如下了:

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 #define ll long long
 8 #define mod 1000000007
 9 struct submix{
10     ll a[5][5];
11 };
12 submix operator * (submix x,submix y){
13     submix res;
14     memset(res.a,0,sizeof(res.a));
15     for (ll k=1;k<=2;++k){
16         for (ll i=1;i<=2;++i){
17             for (ll j=1;j<=2;++j){
18                 res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
19             }
20         }
21     } 
22     return res;
23 } 
24 ll f[1010];
25 ll n;
26 submix ori,enm;
27 submix ksm(submix x,ll k){
28     submix res=ori;
29     while (k){
30         if (k&1){
31             res=res*x;
32         }
33         x=x*x;
34         k=k/2;
35     }
36     return res;
37 }
38 int main(){
39     cin>>n;
40     if (n==1){
41         cout<<"1";
42         return 0;
43     }
44     if (n==2){
45         cout<<"1";
46         return 0;
47     }
48     ori.a[1][1]=1;
49     ori.a[1][2]=1;
50     ori.a[2][1]=1;
51     ori.a[2][2]=0;
52     enm=ksm(ori,n-3);
53     /*cout<<enm.a[1][1]<<endl;
54     cout<<enm.a[1][2]<<endl;
55     cout<<enm.a[2][1]<<endl;
56     cout<<enm.a[2][2]<<endl;*/
57     cout<<(enm.a[1][1]+enm.a[2][1])%mod;
58     return 0;
59 }
View Code

注释语句是我检验输出的,就无视掉吧233

洛谷P1962 斐波那契数列

标签:rar   怎么办   omega   range   int   click   tor   while   main   

原文地址:http://www.cnblogs.com/gjc1124646822/p/7795524.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!