INVARIANT · BIT MANIPULATION · THINK IN BITS
01
00/16
01 / COVER STEP 08 · BIT MANIPULATION
INVARIANT · STEP 08 · COMPLETE STEP
THINK IN BITS

Underneath every integer is 32 switches. This deck teaches you to reach for them: read, set, clear and toggle a single bit, count them with a trick, enumerate every subset with a bitmask, and lean on the one identity that carries the whole topic — a ^ a = 0. Every operator runs live on a 32-cell strip you can step and predict, and each concept lecture is wrapped: prime it, watch it, drill it, then solve the sheet problems it unlocks.

16Problems
6Patterns
11Units
12Live ops
← → ↑ ↓  or  W A S D  navigate SPACE next   DOUBLE-CLICK to advance I index   G goto problem   P predict H hide solutions   T close video   F fullscreen
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
02 / START HERE READ THIS ONE FIRST

HOW THIS DECK WORKS

This is not a list of problems. It is 11 learning units, and every one runs the same four beats. Go in order and the problems stop feeling random.

ASSUMEDA binary trie in unit 09, tagged beyond the sheet. Tries is step 17 and not built yet, so that unit builds one from nothing.

01 INTROWhat the concept is, and what to watch for
02 VIDEOThe lecture, full-width in theatre mode
03 DRILLS2–4 questions checking the lecture landed
04 PROBLEMSThe sheet problems that concept unlocks

Moving around

← ↑Back a slide — or A / W → ↓Forward — or D / S / Space 2×clickDouble-click the right side to advance, left to go back. A single click never moves the deck. IThe index: every problem, clickable, with your progress GJump straight to a problem by its number FFullscreen

While you study

HHide solutions — blurs code and steps so you try first PPredict mode: call the next step before the animation plays it TClose the video — Esc works too ☐ ★Mark solved, or star to revisit. Both are saved automatically.

16 PROBLEMS · EVERY ONE LINKS TO LEETCODE TO SOLVE

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
03 / INDEX PRESS I FROM ANYWHERE

INDEX — ALL 16 PROBLEMS

Click any problem to jump straight to it. Solved ones turn green. Press I from anywhere to come back here. The number is the sheet's row, not your position — the deck teaches in the order that builds, so you will meet them slightly out of numerical sequence.

FUNDAMENTALS · 03
TRICKS · 02
BITMASK · 01
XOR FAMILY · 05
BIT ARITHMETIC · 03
ADVANCED MATHS · 02
SOLVED HAS A LEETCODE LINK
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
04 / SIGNALS WHEN YOU SEE X, REACH FOR Y

WHICH TOOL, AND WHY

Bit manipulation is a small box of tools, each triggered by a specific phrase in the statement. The cards are the cues — “exactly one bit”, “twice except one”, “all subsets” — and the one-line trick each one licenses.

“IS IT A POWER OF TWO” / “EXACTLY ONE BIT SET”

a power of two has a single 1 bit, so n & (n-1) wipes it to zero

n > 0 && (n & (n-1)) == 0O(1)
“COUNT / FLIP / REVERSE THE BITS”

walk the set bits with n & (n-1), or the 32 positions once each

KERNIGHAN COUNT · PER-BIT PASSO(1) per number
“EVERY ELEMENT TWICE EXCEPT ONE” / “FIND THE MISSING ONE”

a ^ a = 0, so XOR-ing everything cancels the pairs and leaves the odd one

XOR SWEEPO(n) time · O(1) space
“GENERATE ALL SUBSETS” (n is small, ≤ ~20)

an n-bit mask IS a subset; count 0..2ⁿ-1 to enumerate them

BITMASK ENUMERATIONO(2ⁿ · n)
“MAXIMUM XOR PAIR IN THE ARRAY”

insert 32-bit numbers into a trie, then greedily take the opposite bit

BINARY TRIE + GREEDY WALKO(n · 32)
“DIVIDE / ADD / MULTIPLY WITHOUT THE OPERATOR”

rebuild arithmetic from shifts: carry is (a & b) << 1, quotient doubles the divisor

SHIFT-AND-ADDO(log n)
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
05 / CONSTRAINTS BEFORE YOU WRITE A LINE

READ THE ANSWER OFF THE CONSTRAINTS

The word is 32 bits, so any per-bit pass is a constant — that is why counting or reversing a number is O(1). Small n (≤ ~20) says “enumerate subsets with a bitmask”; a big array says “one XOR sweep”.

n ≤
BUDGET
WHAT THAT BUYS YOU
n ≤ 20
O(2ⁿ)
small n → enumerate every subset with a bitmask (Power Set, subset-sum DP)
bits = 32
O(32) ≈ O(1)
one pass over the 32 bit positions — count, reverse, flip, per-bit column tricks are constant per number
n ≤ 10⁵
O(n)
a single XOR or linear sweep — Single Number, Missing Number, Minimum Bit Flips
n ≤ 10⁵ · trie
O(n · 32)
insert each number's 32 bits into a trie, then walk it greedily — Maximum XOR
n ≤ 10⁶
O(n log log n)
Sieve of Eratosthenes — Count Primes marks each composite once
exp ≤ 10⁹
O(log n)
fast exponentiation by squaring — halve the exponent every step (Pow)

32-BIT WORD ⇒ PER-BIT WORK IS O(1) · n ≤ 20 ⇒ BITMASK · BIG ARRAY ⇒ XOR SWEEP

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
06 / ROADMAP WHAT YOU ARE ABOUT TO DO

THE WHOLE RUN, 11 UNITS

Eleven units. The first five own a Striver lecture and a live bit-strip; the XOR family is the heart of the topic, and the last two (Max XOR via a trie, and the Advanced-Maths pair) go a step beyond the sheet.

UNIT 01

Bit Fundamentals

▶ 39:033 DRILLS3 PROBLEMS
UNIT 02

Must-Know Tricks

▶ 41:453 DRILLS1 PROBLEM
UNIT 03

Minimum Bit Flips

▶ 7:002 DRILLS1 PROBLEM
UNIT 04

Power Set (Bitmask)

▶ 12:382 DRILLS1 PROBLEM
UNIT 05

Single Number

▶ 7:123 DRILLS2 PROBLEMS
UNIT 06

Single Number II

▶ 31:192 DRILLS1 PROBLEM
UNIT 07

Single Number III

▶ 24:032 DRILLS1 PROBLEM
UNIT 08

XOR of a Range

▶ 9:382 DRILLSNO SHEET ROW
BEYOND THE SHEETUNIT 09

Maximum XOR (Trie on Bits)

NO LECTURE2 DRILLS1 PROBLEM
UNIT 10

Bit Arithmetic

▶ 19:122 DRILLS3 PROBLEMS
BEYOND THE SHEETUNIT 11

Advanced Maths

NO LECTURE2 DRILLS2 PROBLEMS
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
07 / WARMUP LOAD THE PRIMITIVES INTO MEMORY

THE TWO FACTS THE WHOLE DECK LEANS ON

DRILL 01 · RECALL

The one identity the whole XOR half of this deck rests on: what are x ^ x and x ^ 0?

x ^ x = 0, x ^ 0 = x. XOR is 1 only where the two bits differ, so a number XOR-ed with itself is all-zeros, and XOR-ed with zero is unchanged. Add associativity and commutativity and XOR-ing a whole array makes every duplicate annihilate its partner in any order — the survivor is whatever appears an odd number of times. Single Number, Missing Number and Single Number III are all this one fact.

DRILL 02 · TRACE

Read the bits: what is 1 << 4 as a decimal, and which bit position does it set?

16 = 0001 0000, bit 4. Left-shifting 1 by i slides the single set bit up to position i, and its value is 2ⁱ. That shifted 1 is the mask every single-bit operation starts from: AND it to read, OR it to set, AND with its complement to clear, XOR it to toggle.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
08 / INTRO UNIT 01 · Bit Fundamentals

UNIT 01 — Bit Fundamentals

Every integer is a row of 32 switches, and every bit problem is built from four moves on them. Build a mask with 1 << i — a single 1 in position i — then combine it with n: AND reads the bit, OR sets it, AND with ~mask clears it, XOR toggles it. Odd/even is just bit 0; a power of two is a single set bit; and counting the 1s is one loop of n & (n-1). Own these and the rest of the deck is composition.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU READ, FLIP OR COUNT A SINGLE BIT INSIDE A NUMBER?

mask 1<<iAND / OR / XOR / NOTset · clear · togglen & (n-1)power of two
WHAT TO WATCH FOR
  • 01EVERY OP STARTS FROM THE MASK 1<<i — A 1 SLID TO POSITION i
  • 02AND READS · OR SETS · AND ~MASK CLEARS · XOR TOGGLES
  • 03ODD/EVEN IS BIT 0 · POWER OF TWO IS EXACTLY ONE SET BIT
  • 04COUNT SET BITS BY LOOPING n = n & (n-1) — ONCE PER 1, NOT PER BIT
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
09 / VIDEO UNIT 01 · Bit Fundamentals

L1. Introduction to Bit Manipulation | Operators

STRIVER A2Z
Bit Fundamentals
RUNTIME 39:03
AFTER THIS → 3 DRILLS · PROBLEM #01, #02, #03
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
10 / DRILL UNIT 01 · Bit Fundamentals · 1 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

To test whether bit i of n is set, which expression is correct?

(n & (1<<i)) != 0. 1<<i is a mask with a single 1 in position i; ANDing keeps only that bit of n, so the result is non-zero precisely when the bit is set. n & i is meaningless (it ANDs with the index), and n | (1<<i) would set the bit rather than read it. Equivalently, (n >> i) & 1 shifts the bit down to position 0 and masks it.

DRILL 02 · TRACE

n = 13 is 1101. What is n & (n - 1), and what did the operation do?

12 (1100) — the lowest 1 is gone. n - 1 = 12 = 1100 flips bit 0 to 0; ANDing 1101 & 1100 = 1100 = 12. That is exactly one set bit removed. Do it again on 12 and you get 8, then 0 — three steps for three set bits, which is why Kernighan's count loops once per 1 rather than 32 times. The visualiser strikes out the vanishing bit at each step.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
11 / DRILL UNIT 01 · Bit Fundamentals · 2 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · BUG

This “is n a power of two?” check returns true for n = 0, which is wrong. Which line is the bug?

1  bool isPowerOfTwo(int n) {
2      return (n & (n - 1)) == 0;
3  }

Line 2 needs n > 0 &&. The (n & (n-1)) == 0 test is true for any number with at most one set bit — and zero has no set bits, so it slips through. Powers of two are strictly positive, so guard with n > 0. (Negatives in two's complement also fool the bare test, and the guard rules them out too.)

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
12 / MECHANISM UNIT 01 · OPS · CODE MIRRORED

READ · SET · CLEAR · TOGGLE — ALL FROM ONE MASK

Every single-bit operation is the same two-step move: build a mask with a 1 in position i using 1 << i, then combine it with n. AND reads (n & mask), OR sets (n | mask), AND with NOT clears (n & ~mask), and XOR toggles (n ^ mask). Learn to see the mask sliding to position i and the four operators become one idea with four verbs — the primitives every other problem in the deck is built from.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
13 / MECHANISM UNIT 01 · COUNT · CODE MIRRORED

n & (n-1) DROPS THE LOWEST SET BIT — ONE LOOP PER 1

The naive count checks all 32 bits; Brian Kernighan's trick checks only the set ones. n - 1 flips the lowest set bit to 0 and every 0 below it to 1; ANDing that back with n wipes exactly that lowest set bit and leaves the rest untouched. Repeat until n is 0 and you've looped once per set bit — so a number with three 1s costs three iterations, not 32. Watch the rightmost 1 vanish each step; that disappearing bit is the whole algorithm.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
14 / PROBLEM #01 · FUNDAMENTALS · EASY

Power of Two

EASY fundamentals ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Is n a power of two?” A power of two is exactly one set bit, and one set bit is the signature of the n & (n-1) trick.

INTUITION

A power of two in binary is a single 1 followed by zeros (1, 10, 100, …). Clearing its lowest set bit with n & (n-1) therefore leaves exactly zero. Guard n > 0 first, because zero and negatives also make the bare test true.

STEPS
  1. If n <= 0, return false (0 and negatives are never powers of two)
  2. Compute n & (n - 1) — this clears the lowest set bit
  3. If the result is 0, n had exactly one set bit → return true
  4. Otherwise n had two or more set bits → return false
BRUTEO(log n)
OPTIMALO(1)
↕ SCROLL
// Exactly one set bit, and strictly positive.
bool isPowerOfTwo(int n) {
    return n > 0 && (n & (n - 1)) == 0;
}
TIMEO(1)a single AND and comparison, no loop
SPACEO(1)no extra storage
TRAP

Dropping the n > 0 guard. (n & (n-1)) == 0 is also true for n = 0 (no set bits) and misbehaves for negatives in two's complement — both would be wrongly reported as powers of two. The positivity check is not optional.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
15 / PROBLEM #02 · FUNDAMENTALS · EASY

Number of 1 Bits

EASY fundamentals ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Count the 1 bits (Hamming weight).” Counting set bits is the textbook use of Kernighan's n & (n-1) loop.

INTUITION

Instead of testing all 32 positions, repeatedly clear the lowest set bit with n & (n-1) and count how many times you can before n hits zero. Each iteration removes exactly one 1, so the loop runs once per set bit — cheap for sparse numbers.

STEPS
  1. count = 0
  2. While n != 0: n = n & (n - 1) clears the lowest set bit
  3. Increment count each iteration
  4. When n reaches 0, count equals the number of set bits
BRUTEO(32)
OPTIMALO(set bits)
↕ SCROLL
// Kernighan: strip the lowest set bit each loop.
int hammingWeight(uint32_t n) {
    int count = 0;
    while (n != 0) {
        n = n & (n - 1);   // drop the lowest set bit
        count++;
    }
    return count;
}
TIMEO(set bits)one iteration per set bit — at most 32, often far fewer
SPACEO(1)a single counter
TRAP

Looping a fixed 32 times, or using a signed shift. The fixed loop works but the Kernighan version is proportional to the set bits, not the word size. If you do shift instead, use an unsigned type — an arithmetic right shift of a negative int keeps feeding in 1s and never terminates.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
16 / PROBLEM #03 · FUNDAMENTALS · EASY

Counting Bits

EASY fundamentals ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Return the set-bit count for every number 0..n.” The ‘for every i’ plus a cheap relation to a smaller value is a DP-on-bits cue.

INTUITION

Don't count each number from scratch. i has the same set bits as i >> 1 plus one more if i is odd. So dp[i] = dp[i >> 1] + (i & 1) — every answer is built from a smaller, already-computed one in O(1).

STEPS
  1. dp[0] = 0
  2. For i from 1 to n:
  3. dp[i] = dp[i >> 1] + (i & 1) — drop the low bit, add it back if it was 1
  4. Return the dp array
BRUTEO(n · 32)
OPTIMALO(n)
↕ SCROLL
// dp[i] = dp[i>>1] + (i&1): reuse the smaller answer.
vector<int> countBits(int n) {
    vector<int> dp(n + 1, 0);
    for (int i = 1; i <= n; i++)
        dp[i] = dp[i >> 1] + (i & 1);
    return dp;
}
TIMEO(n)each of the n+1 answers is one array lookup plus an add
SPACEO(n)the output array of n+1 counts
TRAP

Recomputing each count independently. Calling an O(32) popcount for every i is O(32n) and misses the point. The whole value here is the recurrence: i >> 1 is a strictly smaller index whose answer you already have, so one lookup plus the parity bit finishes it in O(1).

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
17 / INTRO UNIT 02 · Must-Know Tricks

UNIT 02 — Must-Know Tricks

This lecture is a bag of identities worth memorising outright, each replacing a loop with one line. Swap without a temp — three XORs, because every XOR is its own undo. Isolate the lowest set bit with n & -n (two's-complement negation flips everything above the lowest 1, so ANDing keeps only that bit). Strip the lowest set bit with n & (n-1). And reverse a word by pulling bits off one end and pushing them onto the other. Each is a reflex you compose later.

THE QUESTION THIS LECTURE ANSWERS

WHICH ONE-LINE BIT IDENTITIES REPLACE A WHOLE LOOP?

XOR swapn & -nn & (n-1)lowest set bitreverse a word
WHAT TO WATCH FOR
  • 01SWAP WITH NO TEMP = THREE XORs — EACH XOR UNDOES THE LAST
  • 02n & -n ISOLATES THE LOWEST SET BIT (keeps it, zeroes the rest)
  • 03n & (n-1) STRIPS THE LOWEST SET BIT (zeroes it, keeps the rest)
  • 04REVERSE = SHIFT THE ANSWER LEFT WHILE SHIFTING n RIGHT, 32 TIMES
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
18 / VIDEO UNIT 02 · Must-Know Tricks

L2. Must Know Tricks in Bit Manipulation

STRIVER A2Z
Must-Know Tricks
RUNTIME 41:45
AFTER THIS → 3 DRILLS · PROBLEM #04
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
19 / DRILL UNIT 02 · Must-Know Tricks · 1 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

What does n & -n evaluate to, and how does it differ from n & (n-1)?

n & -n keeps only the lowest set bit; n & (n-1) removes it. In two's complement -n = ~n + 1, which flips every bit above the lowest 1 and leaves that 1 in place, so ANDing with n isolates it (e.g. 12 & -12 = 4). n & (n-1) is the complement move — it zeroes that same bit. Isolate to read the lowest bit, strip to count or clear it.

DRILL 02 · TRACE

Swap with a ^= b; b ^= a; a ^= b; starting a=5, b=9. After the first two lines, what does b hold?

b becomes 5, the old a. After a ^= b, a = 5 ^ 9. Then b ^= a is b = 9 ^ (5 ^ 9) = 5 — the two 9s cancel and old a survives. The last line a ^= b = (5^9) ^ 5 = 9 finishes the swap. Every step is XOR undoing an earlier XOR, which is exactly the x ^ y ^ y = x identity.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
20 / DRILL UNIT 02 · Must-Know Tricks · 2 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Reversing a 32-bit number, why must the accumulator shift left as n shifts right, for exactly 32 iterations?

You pour bits from one end into the other. res = (res << 1) | (n & 1); n >>= 1; takes n's current lowest bit and stacks it as res's newest low bit while old bits shift up. After all 32 positions, the bit that was at position 0 ends at position 31 and vice-versa — a full reversal. Fewer than 32 iterations reverses only part of the word and leaves the high bits wrong.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
21 / MECHANISM UNIT 02 · TRICKS · CODE MIRRORED

SWAP WITH NO TEMP — THREE XORs THAT UNDO EACH OTHER

The classic party trick, and a clean demonstration of XOR's self-inverse property. After a ^= b, a holds the combined pattern; XOR-ing b back out of it recovers the old a into b; XOR-ing that recovered value out of the combined pattern lands the old b in a. Three lines, no third variable, because every XOR is its own undo. In real code you'd just use a temporary — but the reasoning here (that x ^ y ^ y = x) is exactly what powers Single Number and Missing Number.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
22 / PROBLEM #04 · TRICKS · EASY

Reverse Bits

EASY tricks ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Reverse the bits of a 32-bit unsigned integer.” Rearranging bits within a fixed word is a shift-and-pour loop over the 32 positions.

INTUITION

Pull bits off the low end of n one at a time and stack them onto the low end of a growing result, which you shift left first to make room. After 32 rounds the bit that started at position 0 sits at position 31 and vice-versa.

STEPS
  1. result = 0
  2. Repeat 32 times:
  3. result = (result << 1) | (n & 1) — append n's lowest bit
  4. n = n >> 1 — drop the bit you just used
  5. Return result
BRUTEO(32)
OPTIMALO(32) ≈ O(1)
↕ SCROLL
// Pour n's bits, low end first, onto the result's low end.
uint32_t reverseBits(uint32_t n) {
    uint32_t result = 0;
    for (int i = 0; i < 32; i++) {
        result = (result << 1) | (n & 1);   // append lowest bit of n
        n >>= 1;                            // and drop it
    }
    return result;
}
TIMEO(32) ≈ O(1)exactly 32 iterations regardless of input
SPACEO(1)a single accumulator
TRAP

Using a signed type or stopping early. Do the whole thing in an unsigned 32-bit type — a signed right shift of a negative number sign-extends and corrupts the result. And it must be exactly 32 iterations: fewer reverses only part of the word and leaves the high bits wrong.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
23 / INTRO UNIT 03 · Minimum Bit Flips

UNIT 03 — Minimum Bit Flips

Minimum Bit Flips is a two-line problem once you see it: the number of positions you must flip to turn a into b is exactly the number of positions where they differ — and a ^ b has a 1 in precisely those positions. So the answer is the set-bit count of a ^ b. XOR finds the differences; popcount (Kernighan from Unit 1) counts them.

THE QUESTION THIS LECTURE ANSWERS

HOW MANY BIT FLIPS TURN a INTO b?

a ^ b = differencespopcountHamming distancen & (n-1)
WHAT TO WATCH FOR
  • 01FLIP COUNT = NUMBER OF POSITIONS WHERE a AND b DIFFER
  • 02a ^ b HAS A 1 EXACTLY WHERE THEY DIFFER
  • 03SO THE ANSWER IS popcount(a ^ b) — REUSE KERNIGHAN
  • 04TWO OPERATIONS: ONE XOR, THEN COUNT THE SET BITS
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
24 / VIDEO UNIT 03 · Minimum Bit Flips

L3. Minimum Bit Flips to Convert Number

STRIVER A2Z
Minimum Bit Flips
RUNTIME 7:00
AFTER THIS → 2 DRILLS · PROBLEM #05
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
25 / DRILL UNIT 03 · Minimum Bit Flips

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Why is the minimum number of bit flips from a to b equal to the set-bit count of a ^ b?

Differences need one flip each, and XOR marks the differences. A position where a and b already agree needs no flip; a position where they differ needs exactly one. a ^ b puts a 1 in every differing position and 0 elsewhere, so its set-bit count is the total flips — this is the Hamming distance. It's the cleanest compose in the deck: Unit 5's XOR to find the differences, Unit 1's popcount to count them.

DRILL 02 · TRACE

a = 10 (1010), b = 7 (0111). How many flips?

3. 1010 ^ 0111 = 1101. Positions 0, 2 and 3 differ (reading right to left), position 1 agrees — three 1s, so three flips. Counting them with n & (n-1) loops three times: 1101 → 1100 → 1000 → 0. XOR then popcount, and you're done.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
26 / MECHANISM UNIT 03 · FLIPS · CODE MIRRORED

XOR IS THE DISAGREEMENT OPERATOR

A bit has to change exactly where a and b disagree — and that is the definition of XOR, so a ^ b marks every flip needed in one step. What is left is counting the ones, and x &= x-1 clears the lowest set bit each time, so the loop runs once per set bit rather than once per bit of width.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
27 / PROBLEM #05 · TRICKS · EASY

Minimum Bit Flips to Convert Number

EASY tricks ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Minimum flips to convert start into goal.” “Positions that differ” is XOR; “how many” is a set-bit count — popcount(a ^ b).

INTUITION

A flip is needed at exactly the positions where the two numbers disagree. start ^ goal has a 1 in each such position, so the answer is simply the number of set bits in that XOR — the Hamming distance.

STEPS
  1. diff = start ^ goal — 1s mark every differing position
  2. Count the set bits of diff (Kernighan: loop diff &= diff - 1)
  3. That count is the minimum number of flips
  4. Return it
BRUTEO(32)
OPTIMALO(set bits)
↕ SCROLL
// Flips needed = set bits of the XOR (Hamming distance).
int minBitFlips(int start, int goal) {
    int diff = start ^ goal, count = 0;
    while (diff) {
        diff &= diff - 1;   // strip a differing bit
        count++;
    }
    return count;
}
TIMEO(set bits)one XOR plus one iteration per differing bit
SPACEO(1)a counter
TRAP

Comparing digit by digit, or forgetting the XOR reveals the differences for free. There's no need to loop over bit positions manually and compare — start ^ goal already isolates the differing bits, and Kernighan counts them in one pass. In Python, bin(start ^ goal).count('1') is the whole solution.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
28 / INTRO UNIT 04 · Power Set (Bitmask)

UNIT 04 — Power Set (Bitmask)

The power set — every subset of n items — has 2ⁿ members, and an n-bit number is a subset: bit i on means item i is in. So looping a plain integer mask from 0 to 2ⁿ - 1 and reading its bits generates all subsets with no recursion — the outer loop picks the subset, the inner loop reads which items it contains. It's the bitmask version of the pick/not-pick recursion tree.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU LIST ALL 2ⁿ SUBSETS WITH JUST TWO LOOPS?

power set2ⁿ subsetsmask = subset1<<n iterationsbit i ⇔ item i
WHAT TO WATCH FOR
  • 01AN n-BIT MASK IS A SUBSET: BIT i ON ⇔ ITEM i CHOSEN
  • 02OUTER LOOP: mask FROM 0 TO (1<<n)-1 — THAT'S 2ⁿ SUBSETS
  • 03INNER LOOP: FOR EACH i, IF (mask & (1<<i)) ADD nums[i]
  • 04000 IS EMPTY · 111 IS EVERYTHING · NO RECURSION NEEDED
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
29 / VIDEO UNIT 04 · Power Set (Bitmask)

L4. Power Set | Bit Manipulation

STRIVER A2Z
Power Set (Bitmask)
RUNTIME 12:38
AFTER THIS → 2 DRILLS · PROBLEM #06
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
30 / DRILL UNIT 04 · Power Set (Bitmask)

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Why does the loop run from 0 to (1 << n) - 1, and how does a mask value encode a subset?

1<<n = 2ⁿ, and each integer is a membership vector. There are 2ⁿ subsets and 2ⁿ distinct n-bit numbers, so they correspond one-to-one. Reading bit i of the mask (mask & (1<<i)) tells you whether item i is in that subset. Iterating the masks therefore iterates the subsets — the empty set is 0, the full set is all-ones.

DRILL 02 · TRACE

Items are [a, b, c] (index 0,1,2). Which subset does mask 5 = 101 represent?

{a, c}. 5 = 101 has bit 0 and bit 2 set, bit 1 clear. Bit 0 → item a in, bit 1 → item b out, bit 2 → item c in. Reading right-to-left keeps index i aligned with 1<<i. The visualiser lights exactly the chosen cells as the mask counts up.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
31 / MECHANISM UNIT 04 · POWERSET · CODE MIRRORED

EVERY MASK 0..2ⁿ-1 IS ONE SUBSET — NO RECURSION

An n-bit number is a subset: bit i on means item i is chosen. So counting a plain integer mask from 0 to 2ⁿ - 1 and reading its bits enumerates every subset — no recursion, no backtracking, just a loop inside a loop. 000 is the empty set, 111 is everything, and the 2ⁿ values in between are each a distinct combination. It is the cleanest thing bit manipulation buys you: a power set as a for-loop.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
32 / PROBLEM #06 · BITMASK · MED

Subsets

MED bitmask ▶ SOLVE ON LEETCODERecursion 1 built these with pick/not-pick. Every mask 0..2ⁿ-1 is one subset — no recursion at all.
SIGNAL — WHAT GIVES IT AWAY

“Return all subsets of the array” with n small (≤ ~20). List-all over a small n is the bitmask enumeration signature.

INTUITION

Each subset corresponds to an n-bit mask: bit i set means nums[i] is included. Loop mask from 0 to 2ⁿ - 1; for each, read its bits to build one subset. No recursion, no backtracking — the integer is the choice vector.

STEPS
  1. For mask from 0 to (1 << n) - 1:
  2. Start an empty subset
  3. For i from 0 to n-1: if mask has bit i set, add nums[i]
  4. Append the subset to the result
  5. Return all 2^n subsets
BRUTEO(2ⁿ · n)
OPTIMALO(2ⁿ · n)
↕ SCROLL
// Each mask 0..2^n-1 IS a subset; read its bits.
vector<vector<int>> subsets(vector<int>& nums) {
    int n = nums.size();
    vector<vector<int>> res;
    for (int mask = 0; mask < (1 << n); mask++) {
        vector<int> subset;
        for (int i = 0; i < n; i++)
            if (mask & (1 << i))          // is item i chosen?
                subset.push_back(nums[i]);
        res.push_back(subset);
    }
    return res;
}
TIMEO(2ⁿ · n)2ⁿ masks, each scanned across n bits (output aside)
SPACEO(1)O(1) beyond the output list itself
TRAP

Looping the mask only to n instead of 2ⁿ. The outer bound is 1 << n (the number of subsets), not n. Also keep index i aligned with 1<<i when reading bits, and note this only scales while n is small — 2ⁿ explodes past ~20.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
33 / INTRO UNIT 05 · Single Number

UNIT 05 — Single Number

The whole XOR family rests on one fact from the warmup: a ^ a = 0 and a ^ 0 = a, and XOR is order-independent. So XOR-ing an array where every value appears twice except one makes all the pairs annihilate, leaving the lone element — O(n) time, O(1) space, no hash set. Missing Number is the same idea: XOR all the indices 0..n together with all the values, and every present number cancels its index, leaving the one that's absent.

THE QUESTION THIS LECTURE ANSWERS

WHEN EVERYTHING PAIRS UP EXCEPT ONE, HOW DO YOU FIND THE ODD ONE OUT?

a ^ a = 0pairs cancelO(1) spaceindex ^ valuethe survivor
WHAT TO WATCH FOR
  • 01XOR THE WHOLE ARRAY — DUPLICATES CANCEL (a ^ a = 0)
  • 02THE SURVIVOR IS THE ELEMENT WITH NO PARTNER
  • 03MISSING NUMBER: XOR THE INDICES 0..n WITH THE VALUES TOO
  • 04EACH PRESENT VALUE CANCELS ITS INDEX; THE ABSENT ONE REMAINS
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
34 / VIDEO UNIT 05 · Single Number

L5. Single Number-I | Bit Manipulation

STRIVER A2Z
Single Number
RUNTIME 7:12
AFTER THIS → 3 DRILLS · PROBLEM #07, #08
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
35 / DRILL UNIT 05 · Single Number · 1 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Single Number XORs the whole array. Why does the answer fall out, and why is order irrelevant?

Commutativity + self-cancellation. Because x ^ y = y ^ x and x ^ x = 0, you can imagine reordering the array so each duplicate sits next to its twin — every pair becomes 0, and 0 XORed with the lone value leaves that value. No sorting or reordering actually happens; the algebra guarantees it regardless of input order. That's why it's O(1) space where a hash set is O(n).

DRILL 02 · TRACE

Array [4, 1, 2, 1, 2]. What does XOR-ing all five give?

4. 4 ^ 1 ^ 2 ^ 1 ^ 2: the pair of 1s gives 0, the pair of 2s gives 0, leaving 4 ^ 0 ^ 0 = 4. The mechanism slide shows the running value collapsing to 0 each time a pair completes, then holding the survivor. This exact array is what the xor visualiser runs.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
36 / DRILL UNIT 05 · Single Number · 2 OF 2

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · TRANSFER

Missing Number: an array holds n distinct values from 0..n with one absent. How does XOR find the missing one?

XOR the indices and the values into one accumulator. Fold 0 ^ 1 ^ … ^ n together with arr[0] ^ arr[1] ^ …. Every number that is present appears once as a value and once as an index, so it cancels; the number that's missing appears only as an index and survives. It's the same a^a=0 trick with the array's own positions supplying the partners. (Summing with n(n+1)/2 also works but can overflow.)

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
37 / MECHANISM UNIT 05 · XOR · CODE MIRRORED

XOR THE WHOLE ARRAY — THE PAIRS ANNIHILATE

One identity carries the entire family: a ^ a = 0 and a ^ 0 = a. XOR is associative and commutative, so XOR-ing the whole array lets every duplicated value cancel with its partner regardless of order, and whatever appears an odd number of times is left standing. No hash set, no sorting, O(1) space. Watch the running value collapse to 0 each time a pair completes — the survivor is the answer, and every Single-Number variant is a twist on this cancellation.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
38 / PROBLEM #07 · XOR · EASY

Single Number

EASY xor ▶ SOLVE ON LEETCODEYou solved this in Arrays 1 as a one-line trick. Here the point is why XOR annihilates pairs.
SIGNAL — WHAT GIVES IT AWAY

“Every element appears twice except one; find it, in O(1) space.” The O(1)-space + “pairs except one” combo is the XOR sweep.

INTUITION

XOR all the numbers together. Because a ^ a = 0 and XOR is order-independent, every duplicated pair cancels to zero and the single element — which has no partner — is left in the accumulator.

STEPS
  1. x = 0
  2. For each value v in nums: x = x ^ v
  3. Pairs cancel (a ^ a = 0); the lone element survives
  4. Return x
BRUTEO(n) time, O(n) space
OPTIMALO(n)
↕ SCROLL
// XOR everything; duplicates cancel, the single survives.
int singleNumber(vector<int>& nums) {
    int x = 0;
    for (int v : nums) x ^= v;   // a ^ a = 0
    return x;
}
TIMEO(n)a single pass XOR-ing each element once
SPACEO(1)one integer accumulator — no hash set
TRAP

Reaching for a hash set or sort when XOR is free. Those work but cost O(n) space or O(n log n) time; XOR is one pass and one integer. The catch is that it only works when every other element appears an even number of times — if the promise is “thrice except one” (Single Number II), XOR breaks and you need bit counting mod 3.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
39 / PROBLEM #08 · XOR · EASY

Missing Number

EASY xor ▶ SOLVE ON LEETCODEArrays 1 solved this with the sum identity. The XOR route here cannot overflow, which is the reason to prefer it.
SIGNAL — WHAT GIVES IT AWAY

n distinct numbers from 0..n, one missing.” A complete range with a single gap is a XOR (or sum) of index against value.

INTUITION

XOR every index 0..n together with every array value into one accumulator. Each number that's present appears once as a value and once as an index, so it cancels; the missing number appears only as an index and survives. Overflow-free, unlike the sum formula.

STEPS
  1. x = n (covers the top index, since the loop runs 0..n-1)
  2. For i from 0 to n-1: x = x ^ i ^ nums[i]
  3. Present values cancel their indices; the missing index remains
  4. Return x
BRUTEO(n) time, O(n) space
OPTIMALO(n)
↕ SCROLL
// XOR indices against values; the missing index survives.
int missingNumber(vector<int>& nums) {
    int x = nums.size();                 // the index n itself
    for (int i = 0; i < (int)nums.size(); i++)
        x ^= i ^ nums[i];                // each present value cancels its index
    return x;
}
TIMEO(n)one pass folding each index and value once
SPACEO(1)a single accumulator, no overflow risk
TRAP

The sum formula overflows; the index range is off by one. n(n+1)/2 - sum works but can overflow for large n — XOR never does. And the range is 0..n for an array of length n, so seed the accumulator with n (or XOR i up to and including n) or you'll miss the top index.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
40 / INTRO UNIT 06 · Single Number II

UNIT 06 — Single Number II

Single Number II breaks the plain-XOR trick: here every element appears three times except one, and a ^ a ^ a = a, so pairs no longer vanish. The fix generalises the idea to counting each bit position mod 3. For each of the 32 bit columns, add up how many array numbers have that bit set; the triples contribute a multiple of 3, so count % 3 leaves exactly the answer's bit. Rebuild the answer column by column. (The slick ones/twos bitmask automaton does the same in O(1) space.)

THE QUESTION THIS LECTURE ANSWERS

WHEN EVERY ELEMENT APPEARS THREE TIMES EXCEPT ONE, WHY DOES XOR FAIL — AND WHAT REPLACES IT?

appears 3× except onebit count mod 3per-column tallyones/twosgeneralised XOR
WHAT TO WATCH FOR
  • 01PLAIN XOR FAILS: a ^ a ^ a = a, SO TRIPLES DON'T CANCEL
  • 02GENERALISE: FOR EACH BIT POSITION, COUNT SET BITS ACROSS THE ARRAY
  • 03count % 3 AT EACH POSITION IS THE ANSWER'S BIT THERE
  • 04OR THE ones/twos AUTOMATON — SAME LOGIC IN O(1) SPACE
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
41 / VIDEO UNIT 06 · Single Number II

L6. Single Number II | Bit Manipulation

STRIVER A2Z
Single Number II
RUNTIME 31:19
AFTER THIS → 2 DRILLS · PROBLEM #09
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
42 / DRILL UNIT 06 · Single Number II

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Why does the Single Number I trick (XOR everything) fail when each element appears three times instead of twice?

XOR annihilates in pairs, not triples. a ^ a = 0 handles even multiplicities; with an odd count like 3, one copy survives each triple, so XOR-ing everything leaves a jumble of all the tripled values plus the unique one — not the answer. You need a counter that resets every three, which is what per-bit count % 3 (or the ones/twos automaton) provides.

DRILL 02 · RECALL

In the bit-count-mod-3 method, how do you recover the unique element's value?

Tally each column mod 3, then reassemble. Each number that appears three times contributes 0 or 3 to a given bit column, i.e. a multiple of 3; only the unique element contributes an extra 0 or 1. So count % 3 at position i is exactly the unique element's bit i. Set that bit in the result (if (count % 3) ans |= (1 << i)) across all 32 columns and you've rebuilt the answer — O(32n) time, O(1) space.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
43 / MECHANISM UNIT 06 · XOR3 · CODE MIRRORED

XOR CANNOT HELP, SO COUNT THE COLUMNS

The single-number trick fails here: three copies XOR to a, not to 0. So the array is read as columns of bits instead. A value appearing three times contributes 3 to every column it touches, which vanishes mod 3 — so taking each column mod 3 leaves exactly the loner's bits standing, and nothing else can survive.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
44 / PROBLEM #09 · XOR · MED

Single Number II

MED xor ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Every element appears three times except one.” The “thrice except one” wording is the tell that plain XOR won't do — count bits mod 3.

INTUITION

XOR cancels pairs, not triples, so generalise: for each of the 32 bit positions, count how many array numbers have that bit set. Tripled elements contribute a multiple of 3 to each column, so count % 3 leaves exactly the unique element's bit there. Reassemble the answer column by column.

STEPS
  1. ans = 0
  2. For each bit position i in 0..31:
  3. Count how many nums have bit i set; take count % 3
  4. If the remainder is 1, set bit i of ans
  5. Return ans
BRUTEO(n log n) sort, or O(n) space with a map
OPTIMALO(32 · n)
↕ SCROLL
// Each bit column mod 3 leaves the unique element's bit.
int singleNumber(vector<int>& nums) {
    int ans = 0;
    for (int i = 0; i < 32; i++) {
        int count = 0;
        for (int v : nums)
            if (v & (1 << i)) count++;      // tally this column
        if (count % 3) ans |= (1 << i);     // the odd-one-out's bit
    }
    return ans;
}
TIMEO(32 · n)32 bit columns, each tallied across all n numbers
SPACEO(1)a fixed accumulator — no hash map
TRAP

Assuming XOR still works, or mishandling negatives. Plain XOR fails because a ^ a ^ a = a. The bit-count method is robust, but in Python integers are unbounded, so a negative answer needs a two's-complement fixup after bit 31. The ones/twos automaton (ones = (ones ^ v) & ~twos; twos = (twos ^ v) & ~ones) does the same job in true O(1) space.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
45 / INTRO UNIT 07 · Single Number III

UNIT 07 — Single Number III

Single Number III has two loners (each once) among pairs. XOR-ing everything gives a ^ b — not a single answer, but a fingerprint of where a and b differ. Pick any set bit of a ^ b (the lowest, xr & -xr, is easiest): a and b differ there, so it splits the array into two groups — one where that bit is on, one where it's off. Each loner lands in a different group, every pair stays together, so XOR-ing each group gives one answer apiece. One XOR becomes two.

THE QUESTION THIS LECTURE ANSWERS

WITH TWO ELEMENTS APPEARING ONCE, HOW DO YOU SPLIT ONE XOR INTO TWO?

two lonersxr = a ^ bdiffering bitxr & -xrpartition & XOR
WHAT TO WATCH FOR
  • 01XOR ALL → xr = a ^ b (THE BITS WHERE a AND b DIFFER)
  • 02a ≠ b, SO xr HAS AT LEAST ONE SET BIT
  • 03mask = xr & -xr ISOLATES THE LOWEST DIFFERING BIT
  • 04SPLIT ON THAT BIT · XOR EACH HALF · a AND b FALL OUT
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
46 / VIDEO UNIT 07 · Single Number III

L7. Single Number III | Bit Manipulation

STRIVER A2Z
Single Number III
RUNTIME 24:03
AFTER THIS → 2 DRILLS · PROBLEM #10
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
47 / DRILL UNIT 07 · Single Number III

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

After XOR-ing the whole array you have xr = a ^ b. Why does any set bit of xr cleanly separate a from b?

A differing bit separates them by construction. a ^ b is 1 only where the two answers disagree, so at such a position one answer has a 1 and the other a 0 — they must fall into different groups when you partition on that bit. Duplicated values are identical, so both copies share the bit and stay together, cancelling within their group. XOR each group and you get a from one and b from the other.

DRILL 02 · TRACE

If xr = a ^ b = 6 (110), which bit does xr & -xr pick to split on?

Bit 1, the mask 2. 6 = 110; its lowest set bit is position 1. xr & -xr isolates it (110 & 010 = 010). Any set bit of xr would work to split on — the lowest is just the cheapest to grab. You then bucket each number by num & mask and XOR the two buckets separately.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
48 / MECHANISM UNIT 07 · XOR2 · CODE MIRRORED

ANY SET BIT OF a^b SPLITS THE ARRAY IN TWO

XOR-ing everything gives a ^ b, which is not an answer. But any set bit of it is a position where the two loners differ, so partitioning on that bit puts one loner in each group — and every duplicate lands in the same group as its partner, so it still cancels. Two ordinary single-number problems, solved at once.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
49 / PROBLEM #10 · XOR · MED

Single Number III

MED xor ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Exactly two elements appear once; everything else twice.” Two loners with O(1) space is XOR-then-split.

INTUITION

XOR the whole array to get xr = a ^ b. Isolate any set bit of it with xr & -xra and b differ there. Partition the array on that bit and XOR each half separately: pairs cancel within their half, and the two loners land in different halves, giving a and b.

STEPS
  1. xr = XOR of all elements (= a ^ b)
  2. mask = xr & -xr (isolate the lowest differing bit)
  3. For each v: if (v & mask) fold into groupA, else into groupB
  4. groupA and groupB each XOR down to one answer
  5. Return {groupA, groupB}
BRUTEO(n) time, O(n) space
OPTIMALO(n)
↕ SCROLL
// XOR all, split on a differing bit, XOR each half.
vector<int> singleNumber(vector<int>& nums) {
    long xr = 0;
    for (int v : nums) xr ^= v;          // xr = a ^ b
    int mask = xr & (-xr);               // lowest differing bit
    int a = 0, b = 0;
    for (int v : nums) {
        if (v & mask) a ^= v;            // bit set -> group A
        else          b ^= v;            // bit clear -> group B
    }
    return {a, b};
}
TIMEO(n)two linear passes: one to XOR all, one to bucket-and-XOR
SPACEO(1)two accumulators and a mask
TRAP

Splitting on a bit that isn't set in xr. The split bit must be one where a and b differ — i.e. a set bit of a ^ b. xr & -xr guarantees that. Using an arbitrary bit can put both loners in the same bucket and the method collapses. Use a wider type for xr to dodge the -INT_MIN corner.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
50 / INTRO UNIT 08 · XOR of a Range

UNIT 08 — XOR of a Range

XOR of a contiguous range is a closed-form trick, not a loop. XOR-ing 1 ^ 2 ^ … ^ n follows a period-4 pattern in n: if n % 4 == 0 the result is n; == 1 gives 1; == 2 gives n + 1; == 3 gives 0. For an arbitrary range [a, b], use the prefix identity XOR(a..b) = XOR(1..b) ^ XOR(1..a-1) — the same trick as prefix sums, because XOR is its own inverse. It's a concept unit: no LeetCode row, but the identity shows up inside harder problems.

THE QUESTION THIS LECTURE ANSWERS

WHAT IS 1 ^ 2 ^ … ^ n IN CONSTANT TIME?

period-4 patternn % 4prefix XORclosed formown inverse
WHAT TO WATCH FOR
  • 01XOR(1..n) REPEATS EVERY 4: n%4 → {0:n, 1:1, 2:n+1, 3:0}
  • 02SO XOR OF ANY PREFIX IS O(1), NO LOOP
  • 03XOR(a..b) = XOR(1..b) ^ XOR(1..a-1) — PREFIX TRICK
  • 04WORKS BECAUSE XOR IS ITS OWN INVERSE (LIKE PREFIX SUMS)
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
51 / VIDEO UNIT 08 · XOR of a Range

L8. XOR of Numbers in a Given Range

STRIVER A2Z
XOR of a Range
RUNTIME 9:38
AFTER THIS → 2 DRILLS · CONCEPT UNIT
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
52 / DRILL UNIT 08 · XOR of a Range

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

XOR(1..n) has a period-4 closed form. What is it when n % 4 == 0?

When n % 4 == 0, XOR(1..n) = n. The full table is {0: n, 1: 1, 2: n+1, 3: 0}. It arises because consecutive groups of four (4k, 4k+1, 4k+2, 4k+3) XOR to 0, so only the tail position matters. Memorise the four cases and any prefix XOR is a constant-time lookup — no loop over the range.

DRILL 02 · TRACE

Using the pattern, what is 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6?

7. n = 6, 6 % 4 == 2, so XOR(1..6) = n + 1 = 7. Check by hand: 1^2=3, ^3=0, ^4=4, ^5=1, ^6=7. For a sub-range like 3..6 you'd compute XOR(1..6) ^ XOR(1..2) = 7 ^ 3 = 4, again with no loop.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
53 / MECHANISM UNIT 08 · XORRANGE · CODE MIRRORED

FOUR CONSECUTIVE INTEGERS ALWAYS XOR TO ZERO

The running prefix does not wander: it takes only four shapes, decided by n mod 4. Watch it repeat as n passes 4 and 8. Once that is visible the O(n) loop is unnecessary and any range is prefix(r) ^ prefix(l-1), because the shared part cancels itself.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
54 / INTRO UNIT 09 · Maximum XOR (Trie on Bits)

UNIT 09 — Maximum XOR (Trie on Bits)

Maximum XOR of two numbers is where bits meet the trie (a taste of a later sheet topic). Brute force is O(n²); the trick is to store every number's 32-bit representation in a binary trie (each node has a 0-child and a 1-child), then for each number walk the trie from the most significant bit, greedily taking the opposite bit whenever it exists. Choosing the opposite bit forces a 1 into that position of the XOR — and because you go MSB-first, maximising a higher bit always beats anything below it. This unit has no lecture in the playlist; the drills carry it.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU FIND THE MAX-XOR PAIR WITHOUT CHECKING ALL n² PAIRS?

binary trieMSB-firstopposite bitgreedyO(n·32)
WHAT TO WATCH FOR
  • 01BRUTE IS O(n²) — THE TRIE MAKES IT O(n · 32)
  • 02STORE EACH NUMBER'S 32 BITS AS A ROOT-TO-LEAF PATH
  • 03TO MAXIMISE, WALK MSB-FIRST TAKING THE OPPOSITE BIT WHEN IT EXISTS
  • 04OPPOSITE BIT ⇒ A 1 IN THE XOR; HIGH BITS DOMINATE, SO GREEDY IS OPTIMAL
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
55 / DRILL UNIT 09 · Maximum XOR (Trie on Bits)

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

Walking the trie to maximise XOR with a query number, why do you prefer the opposite bit at each step?

Opposite bits differ, and differing bits contribute 1 to the XOR. You want as many high 1-bits in the result as possible. At each level you ask the trie: “is there a stored number whose bit here is the opposite of mine?” If yes, take it — that guarantees a 1 in this position. Falling back to the same bit (a 0 in the XOR) only happens when no opposite branch exists.

DRILL 02 · RECALL

Why must the greedy walk start from the most significant bit rather than the least?

High bits dominate the value. Because 2ᵏ is larger than every lower bit put together, a 1 at position k is worth more than any pattern below it. Greedy only works if you lock in the most valuable bit first, so you descend MSB→LSB, taking the opposite branch when available. Reversing the order could trade a high 1 for several low ones — a strictly worse result.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
56 / MECHANISM UNIT 09 · MAXXOR · CODE MIRRORED

DECIDE THE HIGH BIT FIRST, AND NEVER RECONSIDER

A trie over the bits, walked from the top. At each level the greedy move is the branch that disagrees with the query, because a 1 at a high position outweighs every bit below it combined — so greed is safe here in a way it usually is not. Where the preferred branch is missing there is no choice to make, and that bit of the answer is simply 0.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
57 / PROBLEM #11 · XOR · MED

Maximum XOR of Two Numbers in an Array

MED xor ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Maximum XOR over all pairs.” Maximising XOR bit by bit, over a whole array, is the binary-trie greedy — the O(n²) brute force is the tell you need it.

INTUITION

Insert every number's 32 bits (MSB first) into a binary trie. Then for each number, walk the trie from the top bit, at each level taking the opposite branch when it exists (forcing a 1 into the XOR at that high position) and falling back to the same branch otherwise. Track the best XOR seen.

STEPS
  1. Insert each number into a trie, 31 down to 0, one node per bit
  2. For each number x, walk from the MSB:
  3. At bit b, prefer the child for the opposite of x's bit; else the same child
  4. Accumulate the XOR bit (1 if you took the opposite branch)
  5. Keep the maximum over all numbers
BRUTEO(n²)
OPTIMALO(n · 32)
↕ SCROLL
// Binary trie; greedily take the opposite bit, MSB first.
struct Node { Node* ch[2] = {nullptr, nullptr}; };
int findMaximumXOR(vector<int>& nums) {
    Node* root = new Node();
    for (int x : nums) {                 // insert every number
        Node* cur = root;
        for (int b = 31; b >= 0; b--) {
            int bit = (x >> b) & 1;
            if (!cur->ch[bit]) cur->ch[bit] = new Node();
            cur = cur->ch[bit];
        }
    }
    int best = 0;
    for (int x : nums) {                 // query every number
        Node* cur = root; int cur_xor = 0;
        for (int b = 31; b >= 0; b--) {
            int bit = (x >> b) & 1;
            if (cur->ch[1 - bit]) {      // opposite exists -> a 1 here
                cur_xor |= (1 << b);
                cur = cur->ch[1 - bit];
            } else cur = cur->ch[bit];
        }
        best = max(best, cur_xor);
    }
    return best;
}
TIMEO(n · 32)insert and query are 32 steps each, over n numbers
SPACEO(n · 32)the trie holds up to n·32 nodes
TRAP

Walking LSB-first, or not padding to a fixed width. You must go from the most significant bit so a high 1 is secured before any low bits are considered — greedy is only correct top-down. Insert every number to the same fixed width (e.g. 32 bits) so paths line up; a bit-length hash approach exists too, but the trie is the clean mental model.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
58 / INTRO UNIT 10 · Bit Arithmetic

UNIT 10 — Bit Arithmetic

Arithmetic is just shifts and logic underneath. This lecture rebuilds division without /: to compute a / b, repeatedly double the divisor (b, 2b, 4b, …) while it still fits in the remaining dividend, subtract the largest such multiple, and accumulate the corresponding power of two into the quotient — long division in binary. The same shift-and-logic mindset gives addition without + (sum is XOR, carry is AND shifted left) and the AND of a whole range (the common high prefix). Mind the sign handling and the INT_MIN overflow.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU DIVIDE, ADD, OR AND-A-RANGE USING ONLY SHIFTS AND LOGIC?

shift-and-subtractdouble the divisorquotient bitssign handlingINT_MIN overflow
WHAT TO WATCH FOR
  • 01DIVIDE: DOUBLE THE DIVISOR WHILE IT FITS, SUBTRACT, ADD THAT POWER OF TWO
  • 02IT'S BINARY LONG DIVISION — EACH DOUBLING IS ONE QUOTIENT BIT
  • 03WORK IN long long AND SPLIT OUT THE SIGN — INT_MIN / -1 OVERFLOWS
  • 04ADD = XOR (sum) + (AND << 1) (carry), LOOPED UNTIL CARRY IS 0
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
59 / VIDEO UNIT 10 · Bit Arithmetic

L9. Divide Two Integers without * and /

STRIVER A2Z
Bit Arithmetic
RUNTIME 19:12
AFTER THIS → 2 DRILLS · PROBLEM #12, #13, #14
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
60 / DRILL UNIT 10 · Bit Arithmetic

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

In division-by-shifts, why double the divisor (b, 2b, 4b, …) instead of subtracting b one at a time?

Doubling turns a linear count into a logarithmic one. Naively subtracting the divisor until you can't is O(a/b) — up to ~2³¹ iterations. Instead, find the biggest shifted divisor b << k that still fits, subtract it, add 1 << k to the quotient, and repeat on the remainder. Each step nails one quotient bit from the top down — that's binary long division, O(log²n).

DRILL 02 · RECALL

Which single input pair is the notorious overflow case for integer division, and how do you handle it?

INT_MIN / -1. The mathematical result is +2³¹, one past INT_MAX, so it overflows a signed 32-bit result. Detect it up front and return INT_MAX per the problem's convention. Doing the accumulation in long long and separating the sign avoids intermediate overflow everywhere else.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
61 / MECHANISM UNIT 10 · ARITH · CODE MIRRORED

XOR IS THE SUM, AND IS THE CARRY

Addition with no + anywhere. a ^ b is the sum of every column that does not carry, and (a & b) << 1 is precisely the carries, shifted one place left because that is where a carry belongs. Feeding them back can create new carries, so the two steps repeat until the carry is 0 — it is the schoolbook method with the loop made explicit.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
62 / PROBLEM #12 · ARITHMETIC · MED

Divide Two Integers

MED arithmetic ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Divide without *, / or %.” That prohibition points straight at shift-and-subtract (binary long division).

INTUITION

Work with absolute values in a 64-bit type. Repeatedly find the largest divisor << k that still fits in the remaining dividend, subtract it, and add 1 << k to the quotient. Apply the sign at the end and clamp the INT_MIN / -1 overflow.

STEPS
  1. Special-case INT_MIN / -1 → return INT_MAX
  2. Record the result sign; take long-long absolute values
  3. While dividend >= divisor: double divisor until one more doubling would overshoot
  4. Subtract that shifted divisor; add the matching 1<<k to the quotient
  5. Apply the sign and return
BRUTEO(dividend) — repeated subtraction, TLE
OPTIMALO(log²n)
↕ SCROLL
// Binary long division: double the divisor, subtract, accumulate.
int divide(int dividend, int divisor) {
    if (dividend == INT_MIN && divisor == -1) return INT_MAX;   // overflow
    long a = labs(dividend), b = labs(divisor), quotient = 0;
    bool neg = (dividend < 0) ^ (divisor < 0);
    while (a >= b) {
        long temp = b, mult = 1;
        while ((temp << 1) <= a) { temp <<= 1; mult <<= 1; }    // largest fit
        a -= temp;
        quotient += mult;
    }
    return neg ? -quotient : quotient;
}
TIMEO(log²n)an outer loop over quotient bits, inner doubling loop each O(log n)
SPACEO(1)a handful of 64-bit locals
TRAP

The INT_MIN / -1 overflow, and repeated single subtraction. Subtracting the divisor one at a time is O(dividend) and times out; you must double it. And INT_MIN / -1 = +2³¹ doesn't fit — special-case it to INT_MAX and do the arithmetic in a 64-bit type so the doublings never overflow.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
63 / PROBLEM #13 · ARITHMETIC · MED

Sum of Two Integers

MED arithmetic ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Sum of two integers without + or -.” Addition from logic gates is XOR for the sum, AND-shifted for the carry.

INTUITION

Add binary the way hardware does: the sum-without-carry of two bits is their XOR, and the carry is their AND shifted left one. Loop — new a is the XOR, new b is the shifted carry — until the carry is zero.

STEPS
  1. While b (the carry) is non-zero:
  2. carry = (a & b) << 1 — where both bits are 1, carry left
  3. a = a ^ b — sum without the carry
  4. b = carry — fold the carry back in
  5. Return a
BRUTEO(1) with +, but that's disallowed
OPTIMALO(32)
↕ SCROLL
// sum = XOR, carry = AND << 1, repeat until no carry.
int getSum(int a, int b) {
    while (b != 0) {
        unsigned carry = (unsigned)(a & b) << 1;   // carry bits, shifted
        a = a ^ b;                                  // sum without carry
        b = carry;                                  // propagate
    }
    return a;
}
TIMEO(32)at most 32 carry-propagation rounds
SPACEO(1)two integer registers
TRAP

Signed-overflow on the carry, and Python's unbounded ints. In C++ shift the carry as unsigned to avoid UB. In Python integers never overflow, so the carry loop won't terminate for negative results — mask to 32 bits each round and convert back with two's complement at the end.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
64 / PROBLEM #14 · ARITHMETIC · MED

Bitwise AND of Numbers Range

MED arithmetic ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“Bitwise AND of every number in [left, right].” AND over a contiguous range collapses to the numbers' common binary prefix.

INTUITION

Any bit that changes anywhere in the range becomes 0 in the AND (some number has it off). Only the high bits that left and right share stay 1. So shift both right until they're equal (that's the common prefix), then shift the shared value back left by the same amount.

STEPS
  1. shift = 0
  2. While left != right: right-shift both left and right by 1, increment shift
  3. Now left == right is the common prefix
  4. Return left << shift (pad the stripped low bits back as zeros)
BRUTEO(range) — ANDing every number, TLE
OPTIMALO(log n)
↕ SCROLL
// The AND of a range is the common high prefix of the ends.
int rangeBitwiseAnd(int left, int right) {
    int shift = 0;
    while (left != right) {          // strip differing low bits
        left >>= 1;
        right >>= 1;
        shift++;
    }
    return left << shift;            // pad the low bits back as zeros
}
TIMEO(log n)one shift per differing low bit, at most 32
SPACEO(1)a shift counter
TRAP

ANDing every number in the range. For a wide range that's billions of operations. The insight is that any low bit which flips even once across the range is 0 in the result, so only the shared high prefix of left and right survives — an O(log n) shift, not an O(range) loop. (Equivalently, while (right > left) right &= right - 1;.)

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
65 / INTRO UNIT 11 · Advanced Maths

UNIT 11 — Advanced Maths

Two number-theory staples that sit beside bit manipulation on the sheet, neither with a lecture here. Count Primes uses the Sieve of Eratosthenes: mark every composite by walking multiples of each prime, starting at i·i (smaller multiples were already marked by smaller primes) — O(n log log n). Pow(x, n) uses fast exponentiation: xⁿ = (x^(n/2))², halving the exponent each step for O(log n) — the same halving idea as binary representation, which is why it lives near bits.

THE QUESTION THIS LECTURE ANSWERS

HOW DO YOU SIEVE PRIMES, AND POWER A NUMBER, IN LOG-ISH TIME?

Sieve of Eratosthenesmark from i·isquare-and-multiplyhalve the exponentO(log n)
WHAT TO WATCH FOR
  • 01SIEVE: FOR EACH PRIME i, MARK i·i, i·i+i, … AS COMPOSITE
  • 02START AT i·i — SMALLER MULTIPLES ALREADY MARKED BY SMALLER PRIMES
  • 03FAST POW: x^n = (x^(n/2))², SQUARE-AND-MULTIPLY, O(log n)
  • 04HALVE THE EXPONENT EACH STEP — THE BITS OF n DRIVE IT
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
66 / DRILL UNIT 11 · Advanced Maths

CHECK — CAN YOU ANSWER IT WITHOUT LOOKING BACK?

DRILL 01 · RECALL

In the Sieve of Eratosthenes, why can the inner marking loop start at i·i rather than 2·i?

Smaller multiples were already crossed off. A multiple k·i with k < i also equals i·k, and k has a prime factor ≤ k < i that sieved it earlier. So the first new composite that prime i is responsible for is i·i. Starting there is the standard optimisation and changes nothing about correctness.

DRILL 02 · TRACE

Fast exponentiation computes 3⁵. Using xⁿ = (x^(n/2))² (times an extra x when n is odd), how many multiplications, roughly?

~O(log n) multiplications. 3⁵ = 3⁴ · 3 = (3²)² · 3 = 81 · 3 = 243. You square to climb powers of two (3→9→81) and multiply in an extra x for each set bit of the exponent — five in binary is 101, so two squarings and two multiplies. Naive repeated multiplication is O(n); this is O(log n). Remember to handle negative n by inverting x and guarding INT_MIN.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
67 / MECHANISM UNIT 11 · POWBITS · CODE MIRRORED

THE EXPONENT'S BITS ARE THE SCHEDULE

Filed under maths, but it is a bit problem: 313 where 13 is 01101. The squarings form a ladder computed regardless — each is the previous one squared — and the set bits decide which rungs get multiplied in. Bit 1 is 0, so that squaring is skipped entirely. That is why the cost is log(e) and not e.

THE BIT STRIP
STATE
CODE MIRROR
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
68 / PROBLEM #15 · MATH · MED

Count Primes

MED math ▶ SOLVE ON LEETCODE
SIGNAL — WHAT GIVES IT AWAY

“How many primes below n?” Counting primes up to a bound is the Sieve of Eratosthenes.

INTUITION

Assume every number is prime, then cross out the multiples of each prime you meet. For prime i, start marking at i·i (smaller multiples already have a smaller prime factor) and step by i. Whatever's still unmarked below n is prime.

STEPS
  1. isPrime[0..n-1] = true; 0 and 1 are not prime
  2. For i from 2 while i·i < n:
  3. If isPrime[i], mark isPrime[i·i], i·i+i, … as false
  4. Count the remaining true entries below n
  5. Return the count
BRUTEO(n√n) — trial-dividing each number
OPTIMALO(n log log n)
↕ SCROLL
// Sieve of Eratosthenes: cross out multiples from i*i.
int countPrimes(int n) {
    if (n < 3) return 0;
    vector<bool> isPrime(n, true);
    isPrime[0] = isPrime[1] = false;
    for (int i = 2; (long)i * i < n; i++)
        if (isPrime[i])
            for (int j = i * i; j < n; j += i)   // start at i*i
                isPrime[j] = false;
    int count = 0;
    for (int i = 2; i < n; i++) if (isPrime[i]) count++;
    return count;
}
TIMEO(n log log n)each composite is crossed off by its prime factors — near-linear
SPACEO(n)a length-n boolean array
TRAP

Trial-dividing each number, or starting the inner loop at 2i. Checking primality one number at a time is O(n√n) and too slow; the sieve shares work across all numbers. Starting the marking at i·i (not 2i) skips composites already crossed off, and watch the bound: it's primes below n, so index up to n-1.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
69 / PROBLEM #16 · MATH · MED

Pow(x, n)

MED math ▶ SOLVE ON LEETCODERecursion 1 solved this by halving the exponent. Reading that same halving off the bits of n is the iterative form.
SIGNAL — WHAT GIVES IT AWAY

“Compute xⁿ efficiently.” A power with a large exponent is fast exponentiation (binary / square-and-multiply).

INTUITION

Halve the exponent each step: xⁿ = (x^(n/2))², and multiply in an extra x when n is odd. Iteratively, square x as you shift n right, folding x into the answer whenever the current low bit of n is 1. Handle negative n by inverting.

STEPS
  1. If n < 0: x = 1/x and use |n| (guard INT_MIN in a long)
  2. result = 1
  3. While n > 0: if n is odd, result *= x
  4. x *= x (square the base); n >>= 1 (drop a bit)
  5. Return result
BRUTEO(n) — multiply x by itself n times
OPTIMALO(log n)
↕ SCROLL
// Square-and-multiply: fold x in on each set bit of n.
double myPow(double x, int n) {
    long N = n;                    // widen to avoid INT_MIN overflow
    if (N < 0) { x = 1 / x; N = -N; }
    double result = 1.0;
    while (N > 0) {
        if (N & 1) result *= x;    // this bit of the exponent is 1
        x *= x;                    // square the base
        N >>= 1;                   // next bit
    }
    return result;
}
TIMEO(log n)one squaring per bit of the exponent
SPACEO(1)a couple of accumulators
TRAP

Naive O(n) looping, and the INT_MIN negation. Multiplying x by itself n times is far too slow for large n and can TLE. Squaring halves the exponent each step. And -INT_MIN overflows a 32-bit int, so widen n to a 64-bit type before negating.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
70 / RECALL RETRIEVAL, NOT RECOGNITION

NAME THE TRICK AND WHY IT WORKS

DRILL 01 · TRANSFER

You are told an array has every number twice except two that appear once. Plain XOR of everything gives you a ^ b — now what?

Split on a differing bit. a ^ b has a 1 exactly where a and b differ, so any set bit of it partitions the numbers into “bit on” and “bit off”. a and b land in different buckets, every duplicate lands with its twin, so XOR-ing each bucket leaves one answer apiece. mask = xr & -xr isolates the lowest set bit. That is Single Number III — the whole trick is turning one XOR into two.

DRILL 02 · RECALL

Why does n & (n - 1) clear exactly the lowest set bit, and nothing else?

The borrow stops at the lowest 1. In n - 1 the borrow ripples up through the trailing zeros (turning them to 1s) until it hits the lowest set bit, which becomes 0. Every bit above that is untouched. ANDing n with n-1 therefore agrees on all the high bits and kills exactly the lowest 1 — so looping it counts set bits (Kernighan) and testing (n & (n-1)) == 0 detects a single-bit number (power of two).

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
71 / TRAPS PLAUSIBLE, WRONG, AND SILENT

SIX WAYS TO BE PLAUSIBLY WRONG

Bit bugs compile and return believable numbers: a missing positivity guard, a precedence slip, an XOR sweep on the wrong kind of data, a shift into the sign bit. Every one passes the small test.

SHIFTING BY ≥ 32, OR INTO THE SIGN BIT

1 << 31 overflows a signed 32-bit int (undefined behaviour in C++); use 1u << 31 or a long long. Shifting by 32 or more is also UB. Reverse Bits and any full-word mask hit this — it passes small tests and detonates on the high bit.

POWER OF TWO: FORGETTING n > 0

(n & (n-1)) == 0 is also true for n == 0, which is not a power of two. And for negatives in two's complement it misbehaves. The correct test is n > 0 && (n & (n-1)) == 0.

PRECEDENCE: & AND | BIND LOOSER THAN ==

n & 1 == 0 parses as n & (1 == 0) = n & 0 = 0, always false. Bitwise operators sit below comparison in C/C++/Java precedence — parenthesise: (n & 1) == 0. This one compiles and quietly returns the wrong answer every time.

XOR SWEEP ON DATA THAT ISN'T “PAIRS + ONE”

The a^a=0 trick only isolates the answer when every other element appears an even number of times. Single Number II (each thrice) breaks it — XOR leaves garbage; you need per-bit counting mod 3 instead. Check the multiplicity the problem promises before reaching for XOR.

DIVIDE: OVERFLOW AT INT_MIN / -1

INT_MIN / -1 is +2³¹, which doesn't fit in an int — the one case shift-and-subtract division must special-case and clamp to INT_MAX. Do the work in long long and handle signs separately to avoid it.

TOGGLING WHEN YOU MEANT TO SET

n | mask sets a bit to 1 idempotently; n ^ mask flips it, so applying it twice is a no-op and applying it to an already-set bit clears it. Reaching for XOR when you wanted OR is a classic silent bug — set is |, toggle is ^.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
72 / CHEATSHEET REVISION SURFACE

ONE SCREEN, THE WHOLE DECK

Twelve techniques, one page. The right-hand column is the phrase in the statement that should make each line come to mind — the night-before surface.

ALGORITHM
TIME
SPACE
REACH FOR IT WHEN
Read bit i
O(1)
O(1)
(n & (1<<i)) != 0 — AND with a shifted mask
Set / clear / toggle bit i
O(1)
O(1)
n | mask · n & ~mask · n ^ mask
Count set bits (Kernighan)
O(set bits)
O(1)
loop n = n & (n-1); count — one pass per 1
Power of two
O(1)
O(1)
n > 0 && (n & (n-1)) == 0 — exactly one bit set
Power set (bitmask)
O(2ⁿ·n)
O(1)
for mask 0..2ⁿ-1, read bit i to include item i
Single element (XOR)
O(n)
O(1)
XOR the array; pairs cancel, the odd one survives
Two singles (XOR + split)
O(n)
O(1)
XOR all, split on lowest differing bit, XOR each half
Single Number II
O(32n)
O(1)
count each bit position mod 3 across all numbers
Maximum XOR pair
O(32n)
O(32n)
binary trie of the numbers; greedily take the opposite bit
Divide without /
O(log²n)
O(1)
double the divisor while it fits, subtract, accumulate
Count primes
O(n log log n)
O(n)
Sieve of Eratosthenes — mark each composite once
Pow(x, n)
O(log n)
O(1)
square-and-multiply, halving the exponent each step
INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
73 / CLOSE STEP 08 · COMPLETE STEP

THINK IN BITS

Read, set, clear, toggle; count with n & (n-1); enumerate subsets with a mask; and lean on a ^ a = 0 for the whole Single-Number family. Every operator ran live on the 32-cell strip, and every concept was primed, watched, drilled and applied. Next on the sheet: recursion & dynamic programming, where the bitmask returns as state.

00%
OF THIS DECK SOLVED
← ALL TOPICSSTEP 07 · RECURSIONSTEP 04 · BINARY SEARCH

All 9 playlist lectures are used. XOR-of-a-range (L8) is a concept unit — no judge link was supplied. Maximum XOR (a bit-trie) and the Advanced-Maths pair (Count Primes, Pow) go beyond the sheet at the reader's request and carry no lecture.

INVARIANT · BIT MANIPULATION · THINK IN BITS · COMPLETE STEP
■ TOO SMALL TO READ
1280×720
INVARIANT · STEP 08 · COMPLETE STEP

This one needs a laptop

Not a preference — an arithmetic one. Every slide is a fixed 1280 × 720 stage: a graph animating beside the code that drives it, with the problems laid out two columns wide. It scales as a single piece, so on a screen this size the body text comes out around 4px tall.

Shrinking it further would not help, and rebuilding it to reflow would mean losing the thing that makes it worth reading.

YOUR SCREEN0 × 0
NEEDED1060 × 610
WHAT IS WAITING ON THE LAPTOP
WATCH IT RUN, THEN RUN IT FROM MEMORY
Your progress is saved per device, so anything you tick on the laptop will be waiting there.