// File: s-yata[P]louds-patricia/louds-patricia.cpp
// Function: louds::(anonymous namespace)::BitVector::build()
void build() {
    uint64_t n_blocks = words.size() / 4;
    uint64_t n_ones = 0;
    ranks.resize(n_blocks + 1);
    for (uint64_t block_id = 0; block_id < n_blocks; ++block_id) {
      ranks[block_id].set_abs(n_ones);
      for (uint64_t j = 0; j < 4; ++j) {
        if (j != 0) {
          uint64_t rel = n_ones - ranks[block_id].abs();
          ranks[block_id].rels[j - 1] = rel;
        }

        uint64_t word_id = (block_id * 4) + j;
        uint64_t word = words[word_id];
        uint64_t n_pops = Popcnt(word);
        uint64_t new_n_ones = n_ones + n_pops;
        if (((n_ones + 255) / 256) != ((new_n_ones + 255) / 256)) {
          uint64_t count = n_ones;
          while (word != 0) {
            uint64_t pos = Ctz(word);
            if (count % 256 == 0) {
              selects.push_back(((word_id * 64) + pos) / 256);
              break;
            }
            word ^= 1UL << pos;
            ++count;
          }
        }
        n_ones = new_n_ones;
      }
    }
    ranks.back().set_abs(n_ones);
    selects.push_back(words.size() * 64 / 256);
  }

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movq 0x80(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x79c0
movq 0x18(%rsp), %rdi
shrq $0x2, %rax
movq %rax, 0x78(%rsp)
movq $0x0, 0x70(%rsp)
addq $0x18, %rdi
movq 0x78(%rsp), %rsi
addq $0x1, %rsi
callq 0x5db0
movq $0x0, 0x68(%rsp)
movq 0x68(%rsp), %rax
cmpq 0x78(%rsp), %rax
jae 0x48da
movq 0x18(%rsp), %rdi
addq $0x18, %rdi
movq 0x68(%rsp), %rsi
callq 0x5e50
movq %rax, %rdi
movq 0x70(%rsp), %rsi
callq 0x5e70
movq $0x0, 0x60(%rsp)
cmpq $0x4, 0x60(%rsp)
jae 0x48c5
cmpq $0x0, 0x60(%rsp)
je 0x47b2
movq 0x18(%rsp), %rdi
movq 0x70(%rsp), %rax
movq %rax, 0x8(%rsp)
addq $0x18, %rdi
movq 0x68(%rsp), %rsi
callq 0x5e50
movq %rax, %rdi
callq 0x5c20
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movq 0x8(%rsp), %rax
subq %rcx, %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
movb %al, 0x17(%rsp)
addq $0x18, %rdi
movq 0x68(%rsp), %rsi
callq 0x5e50
movb 0x17(%rsp), %dl
movq 0x60(%rsp), %rcx
subq $0x1, %rcx
movb %dl, 0x5(%rax,%rcx)
movq 0x18(%rsp), %rdi
movq 0x68(%rsp), %rax
shlq $0x2, %rax
addq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rsi
callq 0x8470
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rdi
callq 0x5c40
movq %rax, 0x40(%rsp)
movq 0x70(%rsp), %rax
addq 0x40(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x70(%rsp), %rax
addq $0xff, %rax
shrq $0x8, %rax
movq 0x38(%rsp), %rcx
addq $0xff, %rcx
shrq $0x8, %rcx
cmpq %rcx, %rax
je 0x48a8
movq 0x70(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x48(%rsp)
je 0x48a6
movq 0x48(%rsp), %rdi
callq 0x5c60
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rax
andq $0xff, %rax
cmpq $0x0, %rax
jne 0x487f
movq 0x18(%rsp), %rdi
addq $0x30, %rdi
movq 0x50(%rsp), %rax
shlq $0x6, %rax
addq 0x28(%rsp), %rax
shrq $0x8, %rax
movl %eax, 0x24(%rsp)
leaq 0x24(%rsp), %rsi
callq 0x9980
jmp 0x48a6
movq 0x28(%rsp), %rcx
movl $0x1, %eax
shlq %cl, %rax
xorq 0x48(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x482c
jmp 0x48a8
movq 0x38(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x60(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x60(%rsp)
jmp 0x473c
jmp 0x48c7
movq 0x68(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x68(%rsp)
jmp 0x4703
movq 0x18(%rsp), %rdi
addq $0x18, %rdi
callq 0x5ea0
movq %rax, %rdi
movq 0x70(%rsp), %rsi
callq 0x5e70
movq 0x18(%rsp), %rdi
movq %rdi, %rax
addq $0x30, %rax
movq %rax, (%rsp)
callq 0x79c0
movq (%rsp), %rdi
shlq $0x6, %rax
shrq $0x8, %rax
movl %eax, 0x20(%rsp)
leaq 0x20(%rsp), %rsi
callq 0x9980
addq $0x88, %rsp
retq
nopl (%rax)