In some CP contest (it is important) I have used 2 versions of upper_bound to find upper bound in my std::map:
Algorithm upper bound (1):
auto itr = std::upper_bound(s.begin(),s.end(), somenumber);
if(itr == s.end() || *itr > somenumber2)
{
//dosth
} else
//dosth2
}
std::map::upper_bound (2):
auto itr = s.upper_bound(somenumber);
if(itr == s.end() || *itr > somenumber2)
{
//dosth
} else
//dosth2
}
Both versions works if I put small input by hand. But when comes to ~500.000 input (1) exceeded the time limit (4 seconds) but (2) do the job in 0.5/4.0 second.
I checked at docs algorithm/upper_bound and map/upper_bound and both have O(c log(n)) complexity (I think that in both cases c should be similar.
So the question is - what caused that difference?
The cppreference page for std::upper_bound says that the number of comparisons done is logarithmic, but it also continues:
However, for non-LegacyRandomAccessIterators, the number of iterator increments is linear.
std::map does not have random access iterators and therefore std::upper_bound will be allowed to have linear time complexity in the iterator distance due to increments, while std::map::upper_bound is required to have logarithmic time complexity in the size of the container.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With