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.
To make a long story short, if we do the math, then this problem be solved much faster than the previous suggestions.
The problem boils down to finding minimal m > 0 and n >= 0 such that a[n + m] = a[n].
As pointed out by others Floyd's and Brent's algorithms are nice for this problem. These algorithms are generic and work for any recurrence a[i] = f(a[i-1]), ie, they don't make any assumption about f. For the problem at hand, f(x) = p*x + q and we can buy a lot of time if we use f's mathematical properties. Indeed, one can easily show that
a[n] = s * p^n + q * (p^(n-1) + ... + 1) for all n >= 1.
The arguments are a bit lengthy for here but to give an idea of the math suppose s > 0 and q = 0 (the case where q > 0 brings some but not much complexity). Then
a[n] = s * p^n for all n >= 1.
It follows that
a[n + m] - a[n] = s * (p^m - 1) * p^n.
Consider the case where p is even but not zero. One can find unique integers x and ysuch that p = x * 2^y and x is odd. Analogously, we can find integers u and v such that s = u * 2^v and u is odd. Using this we obtain
a[m + n] - a[n] = x^n * (p^m - 1) * u * 2^(n * y + v).
Since x^n, p^m - 1 and u are odd, the only way for the rhs (and thus for the lhs) to be zero modulo 2^31 is when n * y + v >= 31. We are looking for the minimal n which implies n = ceiling((31 - v) / y). We have shown that
a[m + n] = a[n] mod 2^31 for all m > 0,
that is, the sequence is constant from n onwards. It can also be shown that a[0], ..., a[n] are all distinct. Therefore, the solution to the problem is min(n + 1, N).
When p is odd, the argument is much more complex and relies on a property of the group ((Z/rZ)*, *) where r=2^k is a power of 2, namely, if p^m = 1 modulo r and m is minimal, then m divides 2^(k - 1), ie, m belongs to {1, 2, 4, ..., 2^(k - 1)}.
I've implemented my solution and it took 0s to solve all test cases. For comparison, I've also implemented the Floyd's and Brent's algorithm. An interesting test case is N = 100000000, s = 1, p = 3 and q = 1 for which the answer is N. My solution took 0.0s, Floyd's took 2.5s and Brent took 16.0s.
Bit Array
You are viewing a single comment's thread. Return to all comments →
My implementation is available at [1].
To make a long story short, if we do the math, then this problem be solved much faster than the previous suggestions.
The problem boils down to finding minimal
m > 0
andn >= 0
such thata[n + m] = a[n]
.As pointed out by others Floyd's and Brent's algorithms are nice for this problem. These algorithms are generic and work for any recurrence
a[i] = f(a[i-1])
, ie, they don't make any assumption aboutf
. For the problem at hand,f(x) = p*x + q
and we can buy a lot of time if we usef
's mathematical properties. Indeed, one can easily show thata[n] = s * p^n + q * (p^(n-1) + ... + 1)
for alln >= 1
.The arguments are a bit lengthy for here but to give an idea of the math suppose
s > 0
andq = 0
(the case whereq > 0
brings some but not much complexity). Thena[n] = s * p^n
for alln >= 1
.It follows that
a[n + m] - a[n] = s * (p^m - 1) * p^n
.Consider the case where
p
is even but not zero. One can find unique integersx
andy
such thatp = x * 2^y
andx
is odd. Analogously, we can find integersu
andv
such thats = u * 2^v
andu
is odd. Using this we obtaina[m + n] - a[n] = x^n * (p^m - 1) * u * 2^(n * y + v)
.Since
x^n
,p^m - 1
andu
are odd, the only way for the rhs (and thus for the lhs) to be zero modulo2^31
is whenn * y + v >= 31
. We are looking for the minimaln
which impliesn = ceiling((31 - v) / y)
. We have shown thata[m + n] = a[n] mod 2^31
for allm > 0
,that is, the sequence is constant from
n
onwards. It can also be shown thata[0], ..., a[n]
are all distinct. Therefore, the solution to the problem ismin(n + 1, N)
.When
p
is odd, the argument is much more complex and relies on a property of the group((Z/rZ)*, *)
wherer=2^k
is a power of2
, namely, ifp^m = 1
modulor
andm
is minimal, thenm
divides2^(k - 1)
, ie,m
belongs to{1, 2, 4, ..., 2^(k - 1)}
.I've implemented my solution and it took
0s
to solve all test cases. For comparison, I've also implemented the Floyd's and Brent's algorithm. An interesting test case isN = 100000000
,s = 1
,p = 3
andq = 1
for which the answer isN
. My solution took0.0s
, Floyd's took2.5s
and Brent took16.0s
.[1] http://ideone.com/gFQgqT