Loading W Code...
Standard Template Library - your secret weapon for competitive programming!
vector
Dynamic array
set/map
Sorted unique
stack/queue
LIFO/FIFO
priority_queue
Heap
Imagine cooking with pre-chopped vegetables and pre-made sauces from a grocery store. You do not need to cultivate fields and mill flour from scratch to bake a pizza crust. Instead, you focus on crafting the custom toppings.
The C++ Standard Template Library (STL) is a collection of templates that provides pre-built, highly-optimized data structures and generic algorithms so you don't have to write them yourself.
operator()).#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {5, 2, 8, 1, 9, 3};
// Sort vector in ascending order
sort(v.begin(), v.end());
cout << "Sorted: ";
for (int x : v) cout << x << " "; // 1 2 3 5 8 9
cout << endl;
// Find maximum element
auto maxIt = max_element(v.begin(), v.end());
if (maxIt != v.end()) {
cout << "Max: " << *maxIt << endl; // 9
}
return 0;
}Imagine an expanding dining table. As more guests arrive (more items added), the table extends its leaves to fit them, doubling its capacity when fully filled.
A std::vector is a dynamic array container that automatically grows or shrinks in size as elements are inserted or deleted.
O(1)).size() is the number of active elements, while capacity() is the total allocated slot space. When size == capacity, inserting a new element triggers a relocation to a new, double-sized memory block, running in amortized O(1) time.#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5};
v.push_back(6); // Add 6 to the end
cout << "Size: " << v.size() << endl; // 6
cout << "Index 2: " << v[2] << endl; // 3
v.pop_back(); // Remove last element
// Safe index access with bounds checking
try {
cout << "At index 10: " << v.at(10) << endl;
} catch (const out_of_range& e) {
cout << "Index is out of range!" << endl;
}
return 0;
}Imagine a pair of luggage tags stapled together. One tag has the customer's ID and the second tag has their name, allowing you to route them as a single parcel.
A std::pair is a simple container that holds two values of possibly different types.
.first and .second.first values; if equal, compares second values). This makes pairs highly useful as keys in sets or maps.#include <iostream>
#include <utility>
#include <string>
using namespace std;
int main() {
pair<int, string> student = {101, "Alice"};
cout << "ID: " << student.first << ", Name: " << student.second << endl;
// Nested pair
pair<int, pair<double, double>> point = {1, {4.5, -2.1}};
cout << "X: " << point.second.first << ", Y: " << point.second.second << endl;
return 0;
}Imagine sorting document sheets. You can store them in alphabetized filing cabinets (an ordered Set where sheets remain sorted), or check them into a coat room where each coat is assigned a fast hook number (an Unordered Set where lookup is fast but ordering is random).
O(log n) time.O(1) average time.#include <iostream>
#include <set>
#include <unordered_set>
using namespace std;
int main() {
set<int> sortedSet = {30, 10, 20, 10}; // Duplicates ignored
cout << "Sorted Set: ";
for (int x : sortedSet) cout << x << " "; // 10 20 30
cout << endl;
unordered_set<int> hashSet = {30, 10, 20};
if (hashSet.count(10)) {
cout << "10 is present in the hash set!" << endl;
}
return 0;
}Imagine looking up word definitions. You can open an alphabetical dictionary (an ordered Map sorted by key), or retrieve items from lockers using unique combinations (an Unordered Map using hash lookups).
O(log n) time complexity for search, insertion, and deletion.O(1) average time complexity.#include <iostream>
#include <map>
#include <unordered_map>
#include <string>
using namespace std;
int main() {
map<string, int> ages;
ages["Alice"] = 25;
ages["Bob"] = 30;
cout << "Ages (alphabetical):" << endl;
for (auto& p : ages) {
cout << p.first << ": " << p.second << endl;
}
unordered_map<string, string> phoneBook;
phoneBook["Emergency"] = "911";
cout << "Emergency contact: " << phoneBook["Emergency"] << endl;
return 0;
}Containers manage how elements enter and leave your structures:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
int main() {
stack<int> st;
st.push(10);
st.push(20);
cout << "Stack Top: " << st.top() << endl; // 20
st.pop();
queue<int> q;
q.push(10);
q.push(20);
cout << "Queue Front: " << q.front() << endl; // 10
q.pop();
// Min-Heap configuration
priority_queue<int, vector<int>, greater<int>> minHeap;
minHeap.push(30);
minHeap.push(10);
minHeap.push(20);
cout << "Min-Heap Top: " << minHeap.top() << endl; // 10
return 0;
}Instead of writing manual loops to search, reverse, or aggregate data, you can use generic algorithm templates:
std::sort(begin, end): Sorts a range in ascending order (O(n log n) hybrid Introsort).std::binary_search(begin, end, val): Checks if a value exists in a sorted range (O(log n)).std::accumulate(begin, end, init): Sums all elements in a range.std::max_element(begin, end): Returns an iterator to the largest element.#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
int main() {
vector<int> v = {5, 2, 8, 1, 9, 3};
sort(v.begin(), v.end());
if (binary_search(v.begin(), v.end(), 8)) {
cout << "8 is in the vector!" << endl;
}
int sum = accumulate(v.begin(), v.end(), 0);
cout << "Sum: " << sum << endl; // 28
return 0;
}