Merge pull request #75 from hegdenaveen1/patch-7

Updated logic of fibonacci.cpp
This commit is contained in:
Christian Bender 2017-12-25 15:56:39 +01:00 committed by GitHub
commit 489de17556
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,99 +1,46 @@
//An efficient way to calculate nth fibonacci number faster and simpler than O(nlogn) method of matrix exponentiation
//This works by using both recursion and dynamic programming.
//as 93rd fibonacci exceeds 19 digits, which cannot be stored in a single long long variable, we can only use it till 92nd fibonacci
//we can use it for 10000th fibonacci etc, if we implement bigintegers.
//This algorithm works with the fact that nth fibonacci can easily found if we have already found n/2th or (n+1)/2th fibonacci
//It is a property of fibonacci similar to matrix exponentiation.
#include <iostream>
#include<cstdio>
using namespace std;
const long long MAX = 93;
/*
Efficient method for finding nth term in a fibonacci number sequence.
Uses Dvide and conquer approach
Enter Values from 1
Eg-
1st term = 0;
2nd term = 1;
3rd term = 1;
.
.
.
.
*/
long long a[2][2] = {{1,1},{1,0}};//fibonacci matrix
long long ans[2][2] = {{1,1},{1,0}};//final ans matrix
/*
Working Principal:
long long f[MAX] = {0};
[F(k+1) F(k)] [1 1]^k
| | = | |
[F(k) F(k-1)] [1 0]
where F(k) is the kth term of the Fibonacci Sequence.
*/
void product(long long b[][2],long long k[][2])
long long fib(long long n)
{
/*
Function for computing product of the two matrices b and k
and storing them into the variable ans.
Implementation :
Simple matrix multiplication of two (2X2) matrices.
*/
long long c[2][2];//temporary stores the answer
c[0][0] = b[0][0]*k[0][0]+b[0][1]*k[1][0];
c[0][1] = b[0][0]*k[0][1]+b[0][1]*k[1][1];
c[1][0] = b[1][0]*k[0][0]+b[1][1]*k[1][0];
c[1][1] = b[1][0]*k[0][1]+b[1][1]*k[1][1];
ans[0][0] = c[0][0];
ans[0][1] = c[0][1];
ans[1][0] = c[1][0];
ans[1][1] = c[1][1];
}
if (n == 0)
return 0;
if (n == 1 || n == 2)
return (f[n] = 1);
void power_rec(long long n)
{
/*
Function for calculating A^n(exponent) in a recursive fashion
Implementation:
A^n = { A^(n/2)*A^(n/2) if n is even
{ A^((n-1)/2)*A^((n-1)/2)*A if n is odd
*/
if((n == 1)||(n==0))
return;
else
{
if((n%2) == 0)
{
power_rec(n/2);
product(ans,ans);
}
else
{
power_rec((n-1)/2);
product(ans,ans);
product(ans,a);
}
}
if (f[n])
return f[n];
long long k = (n%2!=0)? (n+1)/2 : n/2;
f[n] = (n%2!=0)? (fib(k)*fib(k) + fib(k-1)*fib(k-1))
: (2*fib(k-1) + fib(k))*fib(k);
return f[n];
}
int main()
{
//Main Function
cout <<"Enter the value of n\n";
long long n;
cin >>n;
if(n == 1)
for(long long i=1;i<93;i++)
{
cout<<"Ans: 0"<<endl;
}
else
{
power_rec(n-1);
cout <<"Ans :"<<ans[0][1]<<endl;
cout << i << " th fibonacci number is " << fib(i) << "\n";
}
return 0;
}