Skip to main content

C++ Standard Template Library Hacks I like

C++’s STL is a boon. Not only is C++ extremely fast, in terms of execution, for programming contests – but the addition of STL makes it an extremely strong contender for my “favorite programming contest language”.


1. __gcd(a, b)

The method to find the gcd of two numbers is __gcd(a, b). (Note: There are TWO underscores, not ONE before the function name)
This method is defined under #include<bits/stdc++.h> and returns the greatest common divisor of integers or longs a and b.
This is my go-to in majority of number theory problems involving GCDs or LCMs.

2. __builtin_popcount(a)

This method returns the number of ones present in the binary notation of the number.
i.e. __builtin_popcount(7) = 3, __builtin_popcount(5) = 2, __builtin_popcount(4) = 1

3. __builtin_ctz(a)

This method returns the number of trailing zeros of a number a. Consequently, I’ve also found this convenient in cases where I’m trying to find the least significant bit of a number.
eg. __builtin_ctz(16) = 4, __builtin_ctz(15) = 0
In fact, this could replace the clever bitwise operation a&-a which directly returns the least significant one of a number.
If the above expression is new to you, consider reading this article from Topcoder on bitwise operations.

4. auto

This is one of my most overused feature of STL, auto for C++ is similar to the enhanced for loop of Java, except here we don’t need to even define the datatype of the iterator as it AUTOmatically is defined.
Here’s a sample.

vector<int> A = {2, 4, 3, 5};

// boring way
for(int i=0; i<A.size(); i++) cout << A[i] << " ";

// fun way
for(auto i: A) cout << i << " ";

And this is incredibly convenient if I had a set, or a map, where I’d otherwise have to define an iterator and use a corresponding exit condition.
Check it -

set<int> s = {8, 2, 3, 5, 9};

// boring way
for(set<int>::iterator i = s.begin(); i!=s.end(); i++) cout << *i << " ";

// fun way 
for(auto i:s) cout << i << " ";


5. swap(a, b)

Literally does what it says.
swap(a, b) swaps the value of a with b and vice versa. Convenient.

6. lower_bound(arr.begin(), arr.end(), val)

This method implements binary search on an array. It assumes the array is sorted, and returns the position at which val must be inserted for the array to remain sorted.
Thus, calling this method on an array {10, 20, 30, 40, 50} with val = 15 would return 1.
The difference between lower_bound and upper_bound is evident when val is also an element present in the array, in which case lower_bound returns an index less than upper_bound.

7. accumulate(arr.begin(), arr.end(), init)

This method is really convenient.
It returns the sum of all elements + init.
Here’s how it looks:

vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int sum = std::accumulate(v.begin(), v.end(), 0);

sum now stores 55 in it.
This method also has a few more parameters that you can modify, such as the mathematical function to apply between an elements and the result of all preceding elements.
The default operation is addition but it can be overridden to support GCD or Multiplication by adding a 4th parameter similar to adding a ‘cmp’ parameter in STL’s sort method.

8. partial_sum(arr.begin(), arr.end())

Another very useful method, it overwrites an array with its own prefix sum.
For example,

vector<int> arr(10, 2); // creates a vector of size 10, populated with values of 2
partial_sum(arr.begin(), arr.end());
for(auto i:arr)cout<<i<<" ";

This outputs 2 4 6 8 10 12 14 16 18 20 and so now range sum queries are O(1), with prefix sum arrays implemented in just a single line.

9. adjacent_difference(arr.begin(), arr.end(), res.begin())

Generates the difference array of arr and stores it in res.
If you aren’t familiar with difference arrays, I would point you to my article on difference arrays which allow you to perform range updates on an array in O(1).
Here’s how that looks:

vector<int> a = {1, 2, 4, 7, 12, 19};
vector<int> b(6);

adjacent_difference(a.begin(), a.end(), b.begin());

for(auto i:b)cout<<i<<" ";

This yields an output of 1 1 2 3 5 7 which if you’ll notice is the difference array of a.

10. iota(arr.begin(), arr.end(), val)

The final method on my list, is iota which populates an array/vector in increasing values starting from val.
Here’s how it looks in code:

vector<int> a(10);
iota(a.begin(), a.end(), 2);

for(auto i:a)cout<<i<<" ";

This yields an output of 2 3 4 5 6 7 8 9 10 11. This is highly convenient when using hash maps, or leveraging them as a component of your main algorithm, such as in the case of disjoint-set-union, or union-find algorithms.

Comments

Popular posts from this blog

Prepare for Competitive Programming

I started learning C++ from scratch during my first year of College. I knew nothing about programming, algorithms or data structures.N ow i am more comfortable with data structure and algorithms. What language should you choose? C++ — Highly recommended! It’s very fast. Implementing different algorithms takes little time because of STL. C++ is accepted in all competitions.  I’ve been using it since my first line of code. C — Go and learn C++ because of STL. If you have knowledge of C, you are ready to code in C++ as well. JAVA — It’s slow. But it has Big Integer class, even if there are very few problems that require using it. If the time limit is tight, you will get Time limit exceeded. Java is not accepted in all competitions. Where can you practice? I recommend  Sphere Online Judge (SPOJ) . It’s effective in terms of quality and quantity. Editorials and solutions are available online if you get stuck while solving problems. Supporting websites  SPOJ Toolkit  and  Prob