Enumerating Subsets & Submasks

O(2^n), submasks O(3^n) total

The bit tricks every mask problem is built on: iterate all 2^n subsets of n items, test/set/clear single bits, and, the one people forget, enumerate all submasks of a given mask in O(3^n) total over all masks with the s = (s-1) & m loop. For n up to ~20, brute force over subsets is often the intended solution, not a fallback.

// use it on

CSES: Apple Division

n <= 20 apples split into two groups: try every subset as group one and take the best difference. 2^20 subsets is about a million, comfortably fast.

// the code

// all subsets of n items
for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++)
        if (mask >> i & 1) { /* item i is in this subset */ }
}

// all submasks of m (skips the empty set; O(3^n) over all m)
for (int s = m; s; s = (s - 1) & m) { /* use submask s */ }

// common one-liners
int cnt = __builtin_popcount(mask);   // number of set bits
int low = mask & -mask;               // lowest set bit
bool has = mask >> i & 1;             // is bit i set?
int with_i = mask | (1 << i), without_i = mask & ~(1 << i);