Problem. people stand in a circle; counting starts at person , and every -th person is removed. Who survives? (Josephus, 1st century; the CP classic.)
| Variant | Method | Cost |
|---|---|---|
| any | , | |
| huge , small | remove a whole lap ( people) at once | |
| (1-indexed): rotate ‘s binary representation left by one | ||
| order of elimination | order-statistics tree / BIT: find the next -th alive | |
| -th eliminated person | the same recurrence on the last people |
long long josephus(long long n, long long k) { // 0-indexed survivor; O(k log n) for large n, O(n) for small n
if (n == 1) return 0;
if (k == 1) return n - 1;
if (k > n) return (josephus(n - 1, k) + k) % n;
long long r = josephus(n - n / k, k) - n % k; // one full pass removes n / k people
if (r < 0) r += n;
else r += r / (k - 1);
return r;
}
long long josephus2(long long n) { // k = 2, 1-indexed: rotate the binary representation left
long long h = 1LL << (63 - __builtin_clzll(n));
return 2 * (n - h) + 1;
}Proof: the recurrences
Linear. After the first removal (person ), relabel the remaining people starting from the next one, so label in the smaller circle is person in the original. The survivor of the smaller circle is , hence . Lap jump. For , one lap removes the people at positions , i.e. people, and the next count starts right after the last removed one, at position . Solve the circle of people recursively, then map back: shift by the survivors at the end of the lap (which come first in the new circle) and re-insert one removed person for every survivors; this is the
r - n % kandr += r / (k - 1)step. Each level shrinks by a factor , so the depth is . . If with , after removals people remain and the count starts at person (0-indexed); for a power of two the starting person survives (each lap halves the circle and keeps the start). So the survivor is in 1-indexed form. Tested against direct simulation for all , .