2
def earliestAndLatest(self, n: int, first: int, second: int) -> List[int]:3
def ceiling_of_log2(x: int) -> int:4
"""Return the ceiling of the integer log 2, i.e. index(MSB) - 1 + (1 if x not pow2)"""5
assert 0 < x < 0x1000000006
# Use power of 2 test. offset is 1 iff x is NOT a power of 27
offset = 1 if (x & (x - 1)) != 0 else 013
# Remove offset to get floor_of_log2. floor(log2(x)) + 1 == ceil(log2(x)) iff x not a power of 2.14
return popcount(x) - 1 + offset16
def popcount(x: int) -> int:17
"""Return the number of set bits in 32 bit unsigned x (Hamming weight)"""18
assert 0 <= x < 0x10000000019
x = x - ((x >> 1) & 0x55555555)20
x = (x & 0x33333333) + ((x >> 2) & 0x33333333)21
return (((x + (x >> 4) & 0xF0F0F0F) * 0x1010101) & 0xFFFFFFFF) >> 2423
def count_trailing_zeroes(x: int) -> int:24
"""Return the number of trailing zeroes in 32 bit unsigned x > 0 (LSB + 1). This method is similar to25
branchless binary search, but there are many other methods using the integer log227
assert 0 < x < 0x10000000029
return 0 # odd x, quick break45
# Base case, we can return instantly46
if first + second == n + 1:49
# This ensures that 'first' is closer to the left than 'second' is to the right.50
# Also, crucially ensures that the sum of first and second is minimal among equivalent configs.51
if first + second >= n + 1:52
first, second = n + 1 - second, n + 1 - first54
first_plus_second = first + second56
# Special case if first + 1 == second, since we then need to find which round will have an even # of players57
if first + 1 != second and first_plus_second >= (n + 1) // 2 + 1:58
if first_plus_second == n:59
# If n is 4k + 2, first is 2k, and second is 2k+2, then parity of n also matters.60
if n % 4 == 2 and first + 2 == second:61
# Using n // 4 instead of n//4 + 1 because trailing_zeroes(x-1) = rounds until x is even62
ans_earliest = 3 + count_trailing_zeroes(n // 4)64
ans_earliest = 3 - (first % 2)68
# If we are in a special case: Players are too far left and close together to meet next round70
ans_earliest = 1 + ceiling_of_log2(71
(n + first_plus_second - 2) // (first_plus_second - 1)73
if first + 1 == second:74
ans_earliest += count_trailing_zeroes(75
((n + (1 << (ans_earliest - 1)) - 1) >> (ans_earliest - 1)) - 178
# ceiling_of_log2 of n is the number of rounds left until there are exactly 2 players remaining, starting at n.79
# This implicitly assumes that optimal strategy for ans_latest is moving 'first' and 'second' to pos. 1 and 280
ans_latest = min(ceiling_of_log2(n), n + 1 - second)82
return [ans_earliest, ans_latest]