Find the K-th Character in String Game II

hard bit manipulation math recursion

Problem

Start with word = "a". For each value in operations, the string doubles in length. If operations[i] == 0, append a plain copy of word to itself. If operations[i] == 1, append a copy in which every letter is shifted to the next letter of the alphabet (with z wrapping back to a). After all operations, return the k-th character (1-indexed). Since k can be up to 1014, you cannot build the string — trace the position instead.

Inputk = 10, operations = [0,1,0,1]
Output"b"
word grows "a" → "aa" → "aabb" → "aabbaabb" → "aabbaabbbbccbbcc". The 10th character is 'b'.

def kthCharacter(k, operations):
    pos = k - 1                 # convert to 0-indexed position
    n = 0                       # smallest n with 2^n >= k
    while (1 << n) < k:
        n += 1
    shifts = 0                  # total +1 alphabet shifts collected
    for i in range(n - 1, -1, -1):
        half = 1 << i           # length of word before operation i
        if pos >= half:         # char lives in the appended second half
            pos -= half         # map back into the first half
            if operations[i] == 1:
                shifts += 1     # type-1 copy shifted this char once
    return chr((shifts % 26) + ord('a'))
function kthCharacter(k, operations) {
  let pos = k - 1n;            // 0-indexed position (BigInt for 1e14)
  let n = 0;                   // smallest n with 2^n >= k
  while ((1n << BigInt(n)) < k) n++;
  let shifts = 0;              // total +1 alphabet shifts collected
  for (let i = n - 1; i >= 0; i--) {
    const half = 1n << BigInt(i);  // length of word before operation i
    if (pos >= half) {         // char lives in the appended second half
      pos -= half;             // map back into the first half
      if (operations[i] === 1) shifts++;  // type-1 copy shifted it once
    }
  }
  return String.fromCharCode((shifts % 26) + 97);
}
char kthCharacter(long k, int[] operations) {
    long pos = k - 1;           // 0-indexed position
    int n = 0;                  // smallest n with 2^n >= k
    while ((1L << n) < k) n++;
    int shifts = 0;             // total +1 alphabet shifts collected
    for (int i = n - 1; i >= 0; i--) {
        long half = 1L << i;    // length of word before operation i
        if (pos >= half) {      // char lives in the appended second half
            pos -= half;        // map back into the first half
            if (operations[i] == 1) shifts++;  // type-1 shifted it once
        }
    }
    return (char) ('a' + shifts % 26);
}
char kthCharacter(long long k, vector<int>& operations) {
    long long pos = k - 1;      // 0-indexed position
    int n = 0;                  // smallest n with 2^n >= k
    while ((1LL << n) < k) n++;
    int shifts = 0;             // total +1 alphabet shifts collected
    for (int i = n - 1; i >= 0; i--) {
        long long half = 1LL << i;  // length of word before operation i
        if (pos >= half) {      // char lives in the appended second half
            pos -= half;        // map back into the first half
            if (operations[i] == 1) shifts++;  // type-1 shifted it once
        }
    }
    return (char) ('a' + shifts % 26);
}
Time: O(n) where n = number of relevant operations ≤ 50 Space: O(1)