1. 程式人生 > >求Fibonacci數列的第n項

求Fibonacci數列的第n項

1,1,2,3,5…..好熟悉的斐波拉契數列,請輸出斐波拉契數列的第n項。

輸入格式

一個數 n

輸出格式

一個數 斐波拉契數列的第n項 ,答案摸10000007;

輸入樣例

4

輸出樣例

3

資料範圍

50% 0<n<=100000;

100% 0<n<=1000000000000。

【解題思路】

設Fibonacci數列的第n項為F(n)。則:

1,遞推:F[1] = F[2] = 1。F[i] = F[i-1] + F[i-2](i>2)。時間複雜度O(n),期望得分50。

2,通項公式:


加上快速冪時間是O(logn)。但會出現精度問題。

3,正解:矩陣乘法


則A=

然後計算A的n-2次方乘上[F[1]F[2]]就可以了。

矩陣乘法的時間複雜度為O(1*2*2),而計算A的n-2次方可以用快速冪。則總時間複雜度為O(4*logn)=O(logn)。

【程式】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL MOD = 10000007LL;
const int Maxn = 5;

struct Tnode{
	int n,m;
	LL map[Maxn][Maxn];
};

Tnode multi(Tnode& x,Tnode& y)
{
	Tnode z;
	z.n = x.n; z.m = y.m;
	for(int i=1;i<=z.n;i++)
	for(int j=1;j<=z.m;j++)
	{
		z.map[i][j] = 0;
		for(int k=1;k<=x.m;k++)
			z.map[i][j] = ( z.map[i][j] + x.map[i][k] * y.map[k][j] ) % MOD;
	}
	return z;
}

Tnode b;

Tnode q_pow(LL p)
{
	if(p == 1) return b;
	Tnode y = q_pow(p/2);
	y = multi(y,y);
	if(p % 2 == 1) y = multi(y,b);
	return y;
}

LL n;
int main()
{
	freopen("Fibonacci.in","r",stdin);
	freopen("Fibonacci.out","w",stdout);
	cin>>n;
	if(n <= 2)
	{
		printf("1\n");
		return 0;
	}
	
	Tnode a;
	a.n = 1; a.m = 2;
	a.map[1][1] = 1; a.map[1][2] = 1;
	
	b.n = 2; b.m = 2;
	b.map[1][1] = 0; b.map[1][2] = 1;
	b.map[2][1] = 1; b.map[2][2] = 1;
	
	Tnode now = q_pow(n-2);
	now = multi(a,now);
	cout<<now.map[1][2];
	
	return 0;
}


相關推薦

UVA 10518 How Many Calls(計算Fibonacci數列n時遞迴呼叫次數)

題目連結: UVA 10518 How Many Calls 分析: 根據公式 Cnt[i]=Cnt[i−1]+Cnt[i−2]+1,且Cnt[0]=Cnt[1]=1. 然後用矩陣快速冪構造矩陣解決就行了。 注意: 輸出必須用”%lld”輸出,用”

Fibonacci數列n7種計算方法:Python列表

前面已經分享了幾種計算Fibonacci數列第n項的方法,詳見Python快速計算Fibonacci數列中第n項的方法和三種Fibonacci數列第n項計算方法及其優劣分析,本文分享第7種(過幾天分享第8種),主要演示列表的append()和pop()這兩個方法和反向索引的用法。如果n小的話,可以只appe

三種Fibonacci數列n計算方法及其優劣分析

感謝國防科技大學劉萬偉老師和中國傳媒大學胡鳳國兩位老師提供的思路,文章作者不能超過8個字元,我的名字就寫個姓吧,名字不寫了^_^。另外,除了本文討論的三種方法,之前的文章中還討論了另外幾種方法,詳見相關閱讀第一篇。 def fibo4(n):     '''遞推法     適用於任意大小的n     使用生

矩陣快速模冪 + 斐波那契數列nFibonacci

兩矩陣相乘,樸素演算法的複雜度是O(N^3)。如果求一次矩陣的M次冪,按樸素的寫法就是O(N^3*M)。既然是求冪,不免想到快速冪取模的演算法,前面有快速冪取模的介紹,a^b %m 的複雜度可以降

斐波拉契數列N的3個寫法(JS)

 題目: 求斐波拉切數列第n個數的值是多少? 數列:1,1,2,3,5,8,13,21...... 第一種,for迴圈,直接求N項 // i代表第三項,res代表第i項的時候的值,通過前面2項相加去實現,n項的時候跳出迴圈,輸出res function fb(n){ v

java遞迴斐波那契數列n

public class Fibonacci { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int f

斐波那契數列N的最後一位

RT,該怎麼求呢? 首先,你可能會想到,順序遍歷求解。 利用通項公式,可以得到斐波那契序列: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34... 那每一項的最後一位就是: 0, 1, 1, 2, 3, 5, 8, 3, 1, 4... 這樣做的效

菲波那切數列數列n三種方法小結

菲波那切數列數列的應用場景還是比較多的,比如可以在考試的時候考你遞迴啊,早上碰到的一道題就是這樣,驕傲地寫下遞迴方程,結果TLE了,然後旁邊的大神給我說了一個叫滾動陣列的東西。。。題目是這樣的You

由遞推公式數列n的值/山理工ACM-1689斐波那契?

題引: Problem Description 給出一個數列的遞推公式,希望你能計算出該數列的第N個數。遞推公式如下: F(n)=F(n-1)+F(n-2)-F(n-3). 其中,F(1)=2,

Java練習題-斐波那契數列n

/** * 求斐波那契數列第n項,n<30,斐波那契數列前10項為 1,1,2,3,5,8,13,21,34,55 * @author Tang * */ public clas

斐波那契數列Nf(N)[矩陣快速冪]

string sin int code char const mat ret truct 矩陣快速冪   定義矩陣A(m*n),B(p*q),A*B有意義當且僅當n=p。即A的列數等於B的行數。   且C=A*B,C(m*q)。   例如:   進入正題,由於現

【C語言】Fibonacci數列前40(迴圈)

程式碼為:  //求Fibonacci數列前40項 #include "stdio.h" int main(){ long int f1,f2,i; f1 = 1; f2 = 1; //賦初始值 for(i = 1;i<=20;i++){//迴圈20次,一次兩個,結

使用線性代數求解斐波那契數列n

一:問題 已知斐波那契數列,f1=1,f2=1,f3=3,f4=5...求第n項的數值 二:問題轉化為線性代數問題 可以得到方程 f(n+2)=f(n+1)+f(n) 為了解決問題,新增方程 f(n+1)=f(n+1) 記向量,則上兩式可以寫作 要求,只需知道,

java基礎練習01--查詢Fibonacci數列n個數

package cn.drc.fibonacci; /** * Fibonacci數列是這樣的一個數列: * 1 1 2 3 5 8 13 21 ... * 求出這個數列第 n 個數是多少 * @author drc * */ public class FibonacciDemo {

遞迴實現Fibonacci數列N個元素的計算

1.1 演算法設計思想   無窮數列1,1,2,3,5,8,13,21,34,55,…,被稱為Fibonacci數列。數列遞迴關係式說明當n大於1時,數列的第n項的值是它前面的兩項之和。它用兩個較小的自變數的函式值來定義較大自變數的函式值,所以需要兩個初始值F(0)和F(1

斐波那契數列n的三種求法

方法1:         利用遞迴方法,但是遞迴看似簡單但是無法處理較大的項數,時間複雜度為o(2^n)。 public class fib_遞迴 { /** * @param args */ public static

斐波那契數列N(C++)

求斐波那契數的第N項,N可以很大但結果不能超過1000位; #include <iostream> #include <memory.h> #include <strin

遞迴用python求解斐波那契數列n

      波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的

求解斐波那契數列n(JavaBigInteger之自底向上迭代)

import java.math.BigInteger; import java.util.*; public class Fab //用迭代法自底向上求解斐波那契數列第n項 { publi

斐波那契數列N

#include<stdio.h> int FibonacciSequence(int n) { int f1=1; int f2=1; int f3=1; for(int i=3;i<=n;i++) { f3=f1+f2; f1=f2;