Given two number N and M. The task is to find the N-th fibonacci number mod M.
In general let FN be the N-th fibonacci number then the output should be FN % M.
The Fibonacci sequence is a series of numbers in which each no. is the sum of two preceding nos. It is defined by the recurrence relation:
F0 = 0 F1 = 1 Fn = Fn-1 + Fn-2
These nos. are in the following sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …
Here N can be large.
Examples:
Input: N = 438, M = 900
Output: 44Input: N = 1548276540, M = 235
Output: 185
Approach:
However, for such values of N, a simple recursive approach to keep calculating N Fibonacci numbers with a time complexity of O(2N) should be avoided. Even an iterative or a Dynamic Programming approach with an algorithm looping for N iterations will not be time-efficient.
This problem can be solved using the properties of Pisano Period.
For a given value of N and M >= 2, the series generated with Fi modulo M (for i in range(N)) is periodic.
The period always starts with 01. The Pisano Period is defined as the length of the period of this series.
To understand it further, let’s see what happens when M is small:
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Fi | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 |
Fi mod 2 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
Fi mod 3 | 0 | 1 | 1 | 2 | 0 | 2 | 2 | 1 | 0 | 1 | 1 | 2 |
For M = 2, the period is 011 and has length 3 while for M = 3 the sequence repeats after 8 nos.
Example:
So to compute, say F2019 mod 5, we’ll find the remainder of 2019 when divided by 20 (Pisano Period of 5 is 20). 2019 mod 20 is 19. Therefore, F2019 mod 5 = F19 mod 5 = 1. This property is true in general.
We need to find the remainder when N is divided by the Pisano Period of M. Then calculate F(N)remainder mod M for the newly calculated N.
Below is the implementation of FN modulo M:
// C++ program to calculate // Fibonacci no. modulo m using // Pisano Period #include <bits/stdc++.h> using namespace std;
// Calculate and return Pisano Period // The length of a Pisano Period for // a given m ranges from 3 to m * m long pisano( long m)
{ long prev = 0;
long curr = 1;
long res = 0;
for ( int i = 0; i < m * m; i++)
{
long temp = 0;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
if (prev == 0 && curr == 1)
res = i + 1;
}
return res;
} // Calculate Fn mod m long fibonacciModulo( long n, long m)
{ // Getting the period
long pisanoPeriod = pisano(m);
n = n % pisanoPeriod;
long prev = 0;
long curr = 1;
if (n == 0)
return 0;
else if (n == 1)
return 1;
for ( int i = 0; i < n - 1; i++)
{
long temp = 0;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
}
return curr % m;
} // Driver Code int main()
{ long n = 1548276540;
long m = 235;
cout << (fibonacciModulo(n, m));
return 0;
} // This code is contributed by subhammahato348 |
// Java program to calculate // Fibonacci no. modulo m using // Pisano Period import java.io.*;
class GFG{
// Calculate and return Pisano Period // The length of a Pisano Period for // a given m ranges from 3 to m * m public static long pisano( long m)
{ long prev = 0 ;
long curr = 1 ;
long res = 0 ;
for ( int i = 0 ; i < m * m; i++)
{
long temp = 0 ;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
if (prev == 0 && curr == 1 )
res= i + 1 ;
}
return res;
} // Calculate Fn mod m public static long fibonacciModulo( long n,
long m)
{ // Getting the period
long pisanoPeriod = pisano(m);
n = n % pisanoPeriod;
long prev = 0 ;
long curr = 1 ;
if (n == 0 )
return 0 ;
else if (n == 1 )
return 1 ;
for ( int i = 0 ; i < n - 1 ; i++)
{
long temp = 0 ;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
}
return curr % m;
} // Driver Code public static void main(String[] args)
{ long n = 1548276540 ;
long m = 235 ;
System.out.println(fibonacciModulo(n, m));
} } // This code is contributor by Parag Pallav Singh |
# Python3 program to calculate # Fibonacci no. modulo m using # Pisano Period # Calculate and return Pisano Period # The length of a Pisano Period for # a given m ranges from 3 to m * m def pisanoPeriod(m):
previous, current = 0 , 1
for i in range ( 0 , m * m):
previous, current \
= current, (previous + current) % m
# A Pisano Period starts with 01
if (previous = = 0 and current = = 1 ):
return i + 1
# Calculate Fn mod m def fibonacciModulo(n, m):
# Getting the period
pisano_period = pisanoPeriod(m)
# Taking mod of N with
# period length
n = n % pisano_period
previous, current = 0 , 1
if n = = 0 :
return 0
elif n = = 1 :
return 1
for i in range (n - 1 ):
previous, current \
= current, previous + current
return (current % m)
# Driver Code if __name__ = = '__main__' :
n = 1548276540
m = 235
print (fibonacciModulo(n, m))
|
// C# program to calculate // Fibonacci no. modulo m using // Pisano Period using System;
class GFG {
// Calculate and return Pisano Period
// The length of a Pisano Period for
// a given m ranges from 3 to m * m
public static long pisano( long m)
{
long prev = 0;
long curr = 1;
long res = 0;
for ( int i = 0; i < m * m; i++) {
long temp = 0;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
if (prev == 0 && curr == 1)
res = i + 1;
}
return res;
}
// Calculate Fn mod m
public static long fibonacciModulo( long n, long m)
{
// Getting the period
long pisanoPeriod = pisano(m);
n = n % pisanoPeriod;
long prev = 0;
long curr = 1;
if (n == 0)
return 0;
else if (n == 1)
return 1;
for ( int i = 0; i < n - 1; i++) {
long temp = 0;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
}
return curr % m;
}
// Driver Code
public static void Main()
{
long n = 1548276540;
long m = 235;
Console.Write(fibonacciModulo(n, m));
}
} // This code is contributed by subham348. |
<script> // javascript program to calculate // Fibonacci no. modulo m using // Pisano Period // Calculate and return Pisano Period // The length of a Pisano Period for // a given m ranges from 3 to m * m function pisano(m)
{ let prev = 0;
let curr = 1;
let res = 0;
for (let i = 0; i < m * m; i++)
{
let temp = 0;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
if (prev == 0 && curr == 1)
res = i + 1;
}
return res;
} // Calculate Fn mod m function fibonacciModulo(n,m)
{ // Getting the period
let pisanoPeriod = pisano(m);
n = n % pisanoPeriod;
let prev = 0;
let curr = 1;
if (n == 0)
return 0;
else if (n == 1)
return 1;
for (let i = 0; i < n - 1; i++)
{
let temp = 0;
temp = curr;
curr = (prev + curr) % m;
prev = temp;
}
return curr % m;
} let n = 1548276540;
let m = 235;
document.write(fibonacciModulo(n, m));
// This code is contributed by vaibhavrabadiya117.
</script> |
185
Pisano Period of 235 is 160. 1548276540 mod 160 is 60. F60 mod 235 = 185. Using Pisano Period, we now need to calculate Fibonacci nos. iteratively for a relatively lower N than specified in the original problem and then calculate FN modulo M.
Time Complexity: O(M2)
Auxiliary Space: O(1)