We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
Hi, I have tried this problem a few times and keep failing due to timeout (a bit frustrating). Here's my code which runs O(n). It is based on the idea that f(n) = 2* f(n-1) - f(n-2) + f(n-m-1). Can someone give any hint what would be a better solution?
The O(logN) algorithms explained there involve polynomial root (or eigenvalues) search and may be quite laborious if you don't have a powerful math library. Also, they involve floating point numbers. Alternatively you have the relatively straightforward matrix exponentation method, that is O(M^3 logN) which still works for us, and only uses integer numbers.
Did not expect the major obstacle to be OverflowError from exponentiation of (sqrt(5)+1)/2. Horrible use of diagonalization without numpy.
EDIT: Learned the Decimal module, which helps in calculating very large decimal value. But got stuck with insufficient decimal.getcontext().prec as the value after exponentiation is very, very large (thousands? millions? or even more of digits), while I want every single digit to the left of the decimal point. I wonder if anything could be done to this intermediate step, as there is still crucial ahead before performing the final modulo opeartion. And the I obtained is also subject to significant error as it is found with np.linalg.eig(). Heck, there is even decimal.Overflow: above Emax!
EDIT 2: When I looked closely, unfortunately, this approach seems to start deviating from the results of the DP approach (which is slower but correct) for (763701899 vs 763701898). Using numpy without Decimal is even worse. When the input is 2000 3 then it is the embarrassing 973324784 vs nan vs 709134169.
EDIT 3: Stupid me to have thought about diagonalization. It's not the only option to achieve matrix exponentiation. Simple recursive divide and conquer like mergesort can do the job. And one more thing, construct your matrix according to .
I am getting wrong answer for test case 11. Others are correct. There is no overflow problem, as I also checked using BigInteger, same result. Can somebody pointing ouut my mistake?
When m == 1, then you have to return pow(2, n, 1e9 + 7), since the recurrent relationship F(m, n) = 2F(m, n - 1) - F(m, n - 2) + F(m, n - m - 1) degenerates into F(m, n) = 2F(m, n - 1).
We take F(1, 1) = 1, so F(m, n) = pow(2, n)
I hope this helps :)
No more comments
Cookie support is required to access HackerRank
Seems like cookies are disabled on this browser, please enable them to open this website
Join us
Create a HackerRank account
Be part of a 26 million-strong community of developers
Please signup or login in order to view this challenge
Hi, I have tried this problem a few times and keep failing due to timeout (a bit frustrating). Here's my code which runs O(n). It is based on the idea that f(n) = 2* f(n-1) - f(n-2) + f(n-m-1). Can someone give any hint what would be a better solution?
Try to convert your recursion to matrix form using these ideas: https://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form
The O(logN) algorithms explained there involve polynomial root (or eigenvalues) search and may be quite laborious if you don't have a powerful math library. Also, they involve floating point numbers. Alternatively you have the relatively straightforward matrix exponentation method, that is O(M^3 logN) which still works for us, and only uses integer numbers.
Did not expect the major obstacle to be
OverflowError
from exponentiation of(sqrt(5)+1)/2
. Horrible use of diagonalization without numpy.EDIT: Learned the
Decimal
module, which helps in calculating very large decimal value. But got stuck with insufficientdecimal.getcontext().prec
as the value after exponentiation is very, very large (thousands? millions? or even more of digits), while I want every single digit to the left of the decimal point. I wonder if anything could be done to this intermediate step, as there is still crucial ahead before performing the final modulo opeartion. And the I obtained is also subject to significant error as it is found withnp.linalg.eig()
. Heck, there is evendecimal.Overflow: above Emax
!EDIT 2: When I looked closely, unfortunately, this approach seems to start deviating from the results of the DP approach (which is slower but correct) for (
763701899
vs763701898
). Usingnumpy
withoutDecimal
is even worse. When the input is2000 3
then it is the embarrassing973324784
vsnan
vs709134169
.EDIT 3: Stupid me to have thought about diagonalization. It's not the only option to achieve matrix exponentiation. Simple recursive divide and conquer like mergesort can do the job. And one more thing, construct your matrix according to .
Now perhaps I'm ready for Problem 109 Darts.
I am getting wrong answer for test case 11. Others are correct. There is no overflow problem, as I also checked using BigInteger, same result. Can somebody pointing ouut my mistake?
I had the same problem. I'd suggest taking a second look at the constraints in the problem statement for a hint.
I still couldn't figure out that particular testcase. Can you please tell what I am doing wrong?
Did you figure it out ?
The case m = 1 is special !
When m == 1, then you have to return pow(2, n, 1e9 + 7), since the recurrent relationship F(m, n) = 2F(m, n - 1) - F(m, n - 2) + F(m, n - m - 1) degenerates into F(m, n) = 2F(m, n - 1). We take F(1, 1) = 1, so F(m, n) = pow(2, n) I hope this helps :)