amitabhmajhi2332005's blog

By amitabhmajhi2332005, history, 2 hours ago, In English

The naive approach and its limits

The most straightforward way to find a value x in an array is a simple for loop:

for (int i = 0; i < n; i++) {
    if (array[i] == x) {
        // x found at index i
    }
}

This works perfectly — but its time complexity is O(n). In the worst case you inspect every element. For arbitrary (unsorted) arrays, this is actually optimal; you have no information about where x might be.

When does this become a problem? With n = 106 and 105 queries, you're doing 1011 operations — about 100× over a typical time limit.

But if the array is sorted, the situation changes entirely. Order carries information. Binary search exploits that information to find any element in O(log n) time.

Method 1 — classic halving

Think of how you look up a word in a dictionary. You open roughly to the middle, check whether the word comes before or after, then repeat on the relevant half. This is exactly what Method 1 implements.

The algorithm maintains an active region [a, b] in the array. At each step it checks the middle element and halves the region, until either the element is found or the region collapses.

int a = 0, b = n-1;
while (a <= b) {
    int k = (a+b)/2;
    if (array[k] == x) {
        // x found at index k
    }
    if (array[k] > x) b = k-1;
    else a = k+1;
}

The active region starts at size n and halves each iteration, giving at most ⌈log₂ n⌉ iterations — hence O(log n).

Method 2 — jump search variant

An alternative that's elegant to reason about: instead of tracking a region, track a jump length and walk forward.

int k = 0;
for (int b = n/2; b >= 1; b /= 2) {
    while (k+b < n && array[k+b] <= x) k += b;
}
if (array[k] == x) {
    // x found at index k
}

The outer loop runs ⌈log₂ n⌉ times and the inner while executes at most twice per jump length — so the total is still** O(log n)**

C++ STL functions

lower_bound	Pointer to first element ≥ x
upper_bound	Pointer to first element > x
equal_range	Both pointers as a pair

If no such element exists, all three point one past the last element. Here's how to check for x:

auto k = lower_bound(array, array+n, x) - array;
if (k < n && array[k] == x) {
    // x found at index k
}

Counting how many times x appears:

auto a = lower_bound(array, array+n, x);
auto b = upper_bound(array, array+n, x);
cout << b-a << "\n";

Using equal_range for the same result in one call:

auto r = equal_range(array, array+n, x);
cout << r.second - r.first << "\n";

In contests, prefer the STL functions whenever you just need a boundary — they're battle-tested and save debugging time. Write Method 1 or 2 explicitly when the predicate is non-standard (e.g. searching on a function's output rather than an array).

Full text and comments »

  • Vote: I like it
  • -17
  • Vote: I do not like it

By amitabhmajhi2332005, history, 3 days ago, In English

Bit Manipulation Technique

All data in a computer is stored as bits — just 0s and 1s. Knowing how to work with them directly is one of the most powerful skills in competitive programming. This post covers bit representations, common operations, and practical applications you'll actually use in contests.

Full text and comments »