Binary Numbers (0–15)

DecBinDecBinDecBinDecBin
000004010081000121100
100015010191001131101
2001060110101010141110
3001170111111011151111

Powers of Two

PowerValuePowerValuePowerValue
12,0484,194,304
24,0968,388,608
48,19216,777,216
816,38433,554,432
1632,76867,108,864
3265,536134,217,728
64131,072268,435,456
128262,144536,870,912
256524,2881,073,741,824
5121,048,5762,147,483,648
1,0242,097,152

Operations

OperationFormulaMeaning / Use
Bitwise ANDa & bintersection of bits
Bitwise ORa | bunion of bits
Bitwise XORa ^ bbits that differ
Bitwise NOT~xinvert every bit
Bitwise NAND~(a & b)NOT of AND
Bitwise NOR~(a | b)NOT of OR
Bitwise XNOR~(a ^ b)bits that are equal
Left shiftn << kmultiply by 2^k
Right shiftn >> kdivide by 2^k (floor)
Two’s complement-x = ~x + 1store negative number
Check odd(n & 1) == 1last bit is 1
Check even(n & 1) == 0last bit is 0
Bit mask for i1 << ionly i-th bit set
Check i-th bit(x & (1 << i)) != 0test if bit is set
Check bit i (shift form)((x >> i) & 1)direct bit test
Set i-th bitx |= (1 << i)force bit to 1
Clear i-th bitx &= ~(1 << i)force bit to 0
Toggle i-th bitx ^= (1 << i)flip bit
Isolate lowest set bitx & -xkeep rightmost 1 only
Clear lowest set bitx & (x - 1)remove rightmost 1
Power of 2 checkx > 0 && (x & (x - 1)) == 0exactly one bit set
Count set bitswhile (x) { x &= x - 1; cnt++; }O(popcount) loop
Popcount builtin__builtin_popcount(x)count 1s
Popcount 64-bit__builtin_popcountll(x)count 1s in long long
Trailing zeros__builtin_ctz(x)index of lowest set bit
Trailing zeros 64-bit__builtin_ctzll(x)lowest set bit index in 64-bit
Leading zeros__builtin_clz(x)leading zero count
Leading zeros 64-bit__builtin_clzll(x)leading zero count in 64-bit
Highest set bit31 - __builtin_clz(x)MSB index in 32-bit
Highest set bit 64-bit63 - __builtin_clzll(x)MSB index in 64-bit
Bit length32 - __builtin_clz(x)number of bits needed
Next power of 21 << (32 - __builtin_clz(x - 1))smallest 2^k >= x
Parity builtin__builtin_parity(x)1 if popcount is odd, else 0
Lowest zero bit value~x & (x + 1)value of rightmost 0
Set lowest zero bitx | (x + 1)turn rightmost 0 into 1
Set lowest unset bitx |= x + 1force rightmost 0 to 1
Clear lowest zero bitx & (x + 1)remove rightmost 0 from pattern
Clear trailing onesx & (x + 1)remove consecutive low 1s
Toggle lowest zero bitx ^ (x + 1)flip bits up to rightmost 0
All bits set in k(1 << k) - 1mask of lowest k bits
Extract lowest k bitsx & ((1 << k) - 1)keep last k bits
Clear lowest k bitsx & ~((1 << k) - 1)zero last k bits
Toggle lowest k bitsx ^ ((1 << k) - 1)flip last k bits
Set lowest k bitsx | ((1 << k) - 1)make last k bits 1
Test subset(a & b) == aa is subset of b
Test disjoint(a & b) == 0no common bits
Remove lowest set bit in loopx &= x - 1drop one set bit
Enumerate all subsetsfor (mask = 0; mask < (1 << n); mask++)iterate over all subsets
Enumerate submasksfor (s = m; s; s = (s - 1) & m)all non-empty submasks of m
Enumerate supersetsfor (s = m; s < (1 << n); s = (s + 1) | m)all supersets
Gray codex ^ (x >> 1)binary → Gray code
Range XOR via prefixP[R] ^ P[L - 1]XOR over subarray [L, R]

Principle of Bit Independence

For bitwise operations (&, |, ^), each bit position is independent of every other bit - there are no carries or borrows between bits. This allows problems to be solved one bit at a time, making it a fundamental technique for per-bit contribution and bitmask algorithms etc.

Fundamental Equation of Bitwise Addition

The Fundamental Equation of Bitwise Addition is a fundamental identity in bit manipulation that expresses ordinary integer addition entirely using bitwise operations. It decomposes binary addition into two independent components: the carry-free sum, computed by XOR, and the carry contribution, identified by AND. Together, these components exactly reconstruct the arithmetic sum.

where

  • a + b - Arithmetic Sum
  • a ⊕ b - Carry-Free Sum
  • a & b - Carry Mask
  • 2(a & b) (equivalently (a & b) << 1) - Carry Contribution

Converse. a ⊕ b = (a + b) - 2(a & b), expressing the carry-free sum in terms of the arithmetic sum and the carry contribution.

Corollary. a + b = (a | b) + (a & b), obtained from the identity a | b = (a ⊕ b) + (a & b).


Parity Equation

equals iff an odd number of bits are set.

void xorSwap(int &a, int &b){
    if(&a==&b) return;
    a^=b;
    b^=a;
    a^=b;
}

MSB-Greedy Principle

In any bitwise optimization processed from MSB to LSB, securing a 1 at bit is always more valuable than any combination of lower bits. Hence greedy decisions at higher bits are never revoked.


Bitmasking

In competitive programming, you often encounter problems with small
constraints, like N <= 20. Whenever you see N hovering around
15 to 22, your brain should immediately scream: Bitmasking.

A bitmask is just an integer, but instead of caring about its decimal
value, we care about its binary representation.

Imagine an array of items: ['Apple', 'Banana', 'Cherry']. Any
subset can be represented with a 3-bit number:

  • bit 0 → Apple, bit 1 → Banana, bit 2 → Cherry.
  • 1 = item is in the subset, 0 = item is out.
000 (0): {}
101 (5): {Apple, Cherry}
111 (7): {Apple, Banana, Cherry}

Bitset

For problems involving huge boolean arrays and set operations at
scale (e.g. reachability, subset-sum, string matching via bitset),
std::bitset<N> packs N bits into words and lets &, |, ^,
<<, >>, and .count() run ~64x faster than a bool[] loop
because the CPU processes 64 bits per instruction. This is a
frequent way to push an O(N^2) DP down to O(N^2 / 64), which
often is the difference between TLE and AC.


Boolean Identities

Identity

Null / Domination

Idempotent

Complement

Double Negation

Commutative

Associative

Distributive

Absorption

De Morgan

XOR / Mixed Identities

Arithmetic Identity

Reversibility

Cancellation

Operator Law Map

LawFollows for
IdentityAND, OR, XOR
Null / DominationAND, OR
IdempotentAND, OR
ComplementAND, OR, XOR
Double NegationNOT
CommutativeAND, OR, XOR
AssociativeAND, OR, XOR
DistributiveAND over OR, OR over AND
AbsorptionAND, OR
De MorganNOT with AND / OR
XOR / Mixed IdentitiesXOR, AND, OR
Arithmetic RelationXOR, AND
ReversibilityXOR
CancellationXOR

Submask Enumeration

For a fixed mask, all of its submasks can be generated in descending order using

Subtracting 1 clears the rightmost set bit and sets all lower bits to 1. Applying & mask removes bits not present in mask, yielding the next valid submask.

Starting from mask, the sequence is strictly decreasing, remains a submask of mask, and eventually reaches 0. Thus every submask is generated exactly once.

If

then the algorithm enumerates exactly

submasks.

// Enumerate all non-zero submasks of mask
for (int submask = mask; submask; submask = (submask - 1) & mask) {
    // process submask
}
 
// Process the empty submask if needed
// submask = 0;

To include 0 in the same loop:

for (int submask = mask;; submask = (submask - 1) & mask) {
    // process submask
    if (submask == 0) break;
}

Tricks

  • Prefix XOR for Range Queries

    Just like a prefix-sum array gives Sum(L, R) = P[R] - P[L-1], and because XOR is its own inverse (x ^ x = 0):

    1. Build a prefix XOR array: P[i] = P[i-1] ^ A[i]
    2. XOR of range [L, R] = P[R] ^ P[L-1]
      Elements from 0 to L-1 appear in both P[R] and P[L-1], so XORing cancels them, leaving only the elements from L to R.