| Resources | |||||
|---|---|---|---|---|---|
| IUSACO | module is based off this | ||||
| CP2 | see description of BSTs and heaps | ||||
In sets and maps where keys (or elements) are stored in sorted order, accessing
or removing the next key higher or lower than some input key k is supported.
Keep in mind that insertion and deletion will take time for sorted sets, which is more than the average insertion and deletion for hashsets, but less than the worst case insertion and deletion for hashsets.
Using Iterators
In Bronze, we avoided discussion of any set operations involving iterators.
In Python, we can use iter() to obtain the iterator object of any iterable.
Using next() on the iterator lets you iterate through the iterable. Below, a
dictionary is used instead of a set because dictionaries keep order.
Iterating through a dictionary representation of an ordered set:
nums = {0: None, 1: None, 2: None, 4: None, 7: None}iterator = iter(nums)print(next(iterator)) # 0print(next(iterator)) # 1print(next(iterator)) # 2print(next(iterator)) # 4print(next(iterator)) # 7
Warning!
As of Python 3.6, dictionaries are ordered by insertion order. For older
versions, you can use an OrderedDict from collections. Keep in mind that
the above representation is of an ordered set, not a sorted set, because Python
does not have sorted sets in its standard library, as you will see in the next
section.
Python's iterators are fundamental to iteration and are used in its for loops and tuple unpacking. This is useful when you want more control over your iteration. It can also be simply used in cases where you just want the first or any element.
Sorted Sets
Python does not have a sorted set nor a sorted map, so see the C++ or Java if you want an implementation from the standard library. However, if you are still curious regarding the Python implementation, you can find an AVL tree representation of a sorted set below.
| Resources | |||||
|---|---|---|---|---|---|
| DSA Python | definition and implementation of AVL Trees in Python | ||||
Warning!
You are not expected to know how to create an AVL tree in USACO Silver, nor is it recommended to do so for a representation of a sorted set since other languages have sorted sets built-in.
Since some online judges include additional libraries, an implementation of
sorted sets from the sortedcontainers library (which is not included in most
online judges like USACO) is shown below. All operations shown below are
time, except for its
initialization.
from sortedcontainers import SortedSetsorted_set = SortedSet([5, 1, 3, 2])print(sorted_set) # SortedSet([1, 2, 3, 4, 7])# Add elementssorted_set.add(4)sorted_set.add(6)print(sorted_set) # SortedSet([1, 2, 3, 4, 5, 6])
One limitation of sorted sets is that we can't efficiently access the largest element in the set, or find the number of elements in the set greater than some arbitrary . In C++, these operations can be handled using a data structure called an order statistic tree.
Sorted Maps
Sorted maps in Python can be created by adding a dictionary to a sorted set, where each element in the sorted set is a key in the dictionary and values can be assigned with the dictionary. This is the most straightforward implementation, and the ground up implementation of a sorted set can be found in the above section.
Additionally, you can implement a SortedDict with the sortedcontainers
library. All operations shown below are time, except for
an initialization and time to get all
items, keys, or values.
from sortedcontainers import SortedDictsorted_map = SortedDict({1: "one", 4: "four", 3: "three"})print(sorted_map) # SortedDict({1: 'one', 3: 'three', 4: 'four'})# Add elementssorted_map[2] = "two"sorted_map[5] = "five"# Output SortedDict({1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'})
Multisets
A multiset is a sorted set that allows multiple copies of the same element.
While there is no multiset in Java, we can implement one using the TreeMap
from values to their respective frequencies. We declare the TreeMap
implementation globally so that we can write functions for adding and removing
elements from it. The first, last, higher, and lower operations still
function as intended; just use firstKey, lastKey, higherKey, and
lowerKey respectively.
static TreeMap<Integer, Integer> multiset = new TreeMap<Integer, Integer>();public static void main(String[] args) { ... }static void add(int x) {if (multiset.containsKey(x)) {multiset.put(x, multiset.get(x) + 1);} else {multiset.put(x, 1);}
Introductory Problems
| Status | Source | Problem Name | Difficulty | Tags | ||
|---|---|---|---|---|---|---|
| CSES | Easy | Show TagsSorted Set | ||||
| YS | Easy | Show TagsSorted Set | ||||
| CSES | Easy | Show TagsSorted Set | ||||
| CSES | Easy | Show TagsBinary Search, Greedy, LIS, Sorted Set | ||||
Harder Example - Bit Inversions
Focus Problem – try your best to solve this problem before continuing!
View Internal SolutionSolution
We'll use iterators extensively.
Let the bit string be . In the set dif, we store
all indices such that (including and ). If the
elements of dif are , then the longest length is
equal to
We can store each of these differences in a multiset ret; after each
inversion, we'll need to output the maximum element of ret.
Inverting a bit at a 0-indexed position x corresponds to inserting x into
dif if it not currently present or removing x if it is, and then doing the
same with x+1. Whenever we insert or remove an element of dif, we should
update ret accordingly.
Warning!
Java solutions are too slow for the CSES. Use C++ instead to get AC.
import java.io.*;import java.util.*;class BitInversion {public static TreeMap<Integer, Integer> ret = new TreeMap<Integer, Integer>();public static String s;public static int m;public static Set<Integer> dif = new TreeSet<Integer>();public static void modify(int x) {
Note that multiset has a high constant factor, so replacing ret with a
priority queue and an array that stores the number of times each integer occurs
in the priority queue reduces the runtime by a factor of 2.
import java.io.*;import java.util.*;class BitInversion {public static PriorityQueue<Integer> pq =new PriorityQueue<Integer>(Collections.reverseOrder());public static String s;public static int m;public static TreeSet<Integer> dif = new TreeSet<Integer>();public static int cnt[];
Harder Problems
| Status | Source | Problem Name | Difficulty | Tags | ||
|---|---|---|---|---|---|---|
| Silver | Normal | Show TagsPriority Queue, Sorted Set | ||||
| CF | Normal | Show TagsGreedy, Multiset, Sorting | ||||
| CSES | Normal | Show TagsGreedy, Sorted Set, Sorting | ||||
| Gold | Normal | Show TagsLinked List, Sorted Set | ||||
| CF | Hard | Show TagsGreedy, Sorted Set, Sorting | ||||
| CF | Hard | Show TagsSorted Set | ||||
| Gold | Hard | Show TagsSorted Set | ||||
| Gold | Hard | Show TagsGreedy, Sorted Set, Sorting | ||||
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!