// File: dgboy2000[P]compress/compress.cpp
// Function: DATCompression::burrows_wheeler_decode(std::vector<int, std::allocator<int>>)
vector<int> DATCompression::burrows_wheeler_decode(vector<int> data) {
    int n = data.size() - 4;
    long int dollar_pos = 256*256*data[n+1] + 256*data[n+2] + data[n+3];
    int bwt_size = n + 1;
    
    pair<int,int> *f = (pair<int,int> *) calloc(bwt_size, sizeof(pair<int,int>));
    int *t = (int *) calloc(bwt_size, sizeof(int));
    vector<int> s;
    s.resize(n);
    
    for (int i=0; i<bwt_size; ++i) f[i] = pair<int,int>(data[i], i);
    f[dollar_pos].first = INT_MIN;
    stable_sort(f, f + bwt_size, pair_comparator);
    
    for (int i=0; i<bwt_size; ++i) t[f[i].second] = i;
    free(f);
    
    int last_t = dollar_pos;
    for (vector<int>::reverse_iterator viter = s.rbegin(); viter != s.rend(); ++viter) {
        last_t = t[last_t];
        *viter = data[last_t];
    }
    free(t);
    
    return s;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdx, -0x90(%rbp)
movq %rdi, %rax
movq -0x90(%rbp), %rdi
movq %rax, -0x80(%rbp)
movq %rax, %rcx
movq %rcx, -0x98(%rbp)
movq %rax, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdi, -0x18(%rbp)
callq 0x90a0
movq -0x90(%rbp), %rdi
addl $-0x4, %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
incl %eax
movslq %eax, %rsi
callq 0x8db0
movq -0x90(%rbp), %rdi
movl (%rax), %eax
shll $0x10, %eax
movl %eax, -0x88(%rbp)
movl -0x1c(%rbp), %eax
addl $0x2, %eax
movslq %eax, %rsi
callq 0x8db0
movq -0x90(%rbp), %rdi
movq %rax, %rcx
movl -0x88(%rbp), %eax
movl (%rcx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movl %eax, -0x84(%rbp)
movl -0x1c(%rbp), %eax
addl $0x3, %eax
movslq %eax, %rsi
callq 0x8db0
movq %rax, %rcx
movl -0x84(%rbp), %eax
movl (%rcx), %ecx
addl %ecx, %eax
cltq
movq %rax, -0x28(%rbp)
movl -0x1c(%rbp), %eax
incl %eax
movl %eax, -0x2c(%rbp)
movslq -0x2c(%rbp), %rdi
movl $0x8, %esi
callq 0x2150
movq %rax, -0x38(%rbp)
movslq -0x2c(%rbp), %rdi
movl $0x4, %esi
callq 0x2150
movq -0x80(%rbp), %rdi
movq %rax, -0x40(%rbp)
movb $0x0, -0x41(%rbp)
callq 0x8d20
movq -0x80(%rbp), %rdi
movslq -0x1c(%rbp), %rsi
callq 0x92b0
jmp 0x4d4b
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x4db9
movq -0x90(%rbp), %rdi
movslq -0x58(%rbp), %rsi
callq 0x8db0
movq %rax, %rsi
leaq -0x60(%rbp), %rdi
leaq -0x58(%rbp), %rdx
callq 0x9380
jmp 0x4d7c
movq -0x38(%rbp), %rdi
movslq -0x58(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
leaq -0x60(%rbp), %rsi
callq 0x93b0
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x4d52
movq -0x80(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
callq 0x8f20
jmp 0x4eeb
movq -0x38(%rbp), %rax
movq -0x28(%rbp), %rcx
movl $0x80000000, (%rax,%rcx,8) # imm = 0x80000000
movq -0x38(%rbp), %rdi
movslq -0x2c(%rbp), %rax
leaq (%rdi,%rax,8), %rsi
leaq 0x13b5(%rip), %rdx      # 0x6190
callq 0x93e0
jmp 0x4de2
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x4e13
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
movslq -0x64(%rbp), %rsi
movslq 0x4(%rcx,%rsi,8), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x4de9
movq -0x38(%rbp), %rdi
callq 0x22a0
movq -0x80(%rbp), %rsi
movq -0x28(%rbp), %rax
movl %eax, -0x68(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x9430
movq -0x80(%rbp), %rsi
leaq -0x78(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x94b0
movq -0xa8(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x9480
movb %al, -0x99(%rbp)
jmp 0x4e5c
movb -0x99(%rbp), %al
testb $0x1, %al
jne 0x4e68
jmp 0x4ebf
movq -0x90(%rbp), %rdi
movq -0x40(%rbp), %rax
movslq -0x68(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x68(%rbp)
movslq -0x68(%rbp), %rsi
callq 0x8db0
movl (%rax), %eax
movl %eax, -0xb4(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x9500
movq %rax, -0xb0(%rbp)
jmp 0x4ea0
movq -0xb0(%rbp), %rax
movl -0xb4(%rbp), %ecx
movl %ecx, (%rax)
leaq -0x70(%rbp), %rdi
callq 0x9530
jmp 0x4eba
jmp 0x4e30
movq -0x40(%rbp), %rdi
callq 0x22a0
movb $0x1, -0x41(%rbp)
testb $0x1, -0x41(%rbp)
jne 0x4edb
movq -0x80(%rbp), %rdi
callq 0x8f20
movq -0x98(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x2380
nopw %cs:(%rax,%rax)