// File: sharmaeklavya2[P]ctmeans/src/lib/kdtree.cpp
// Function: get_kd_tree(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>, Matrix const&, int, KDNode*)
KDNode* get_kd_tree(
    std::vector<int>::iterator begin,
    std::vector<int>::iterator end,
    const Matrix& X, int depth, KDNode* parent
    ) {
    auto size = end - begin;
    if(size == 0) {
        return nullptr;
    }
    else {
        auto size1 = size / 2;
        std::vector<int>::iterator mid = begin + size1;
        if(size > 1) {
            std::nth_element(begin, mid, end, ColComparator(X, depth % X.cols()));
        }
        KDNode* root = new KDNode(depth, *mid, parent);
        int d = X.cols();
        root->cmin.reserve(d);
        root->cmin.assign(X.begin_row(root->point), X.end_row(root->point));
        root->cmax = root->cmin;

        KDNode* left = get_kd_tree(begin, mid, X, depth+1, root);
        KDNode* right = get_kd_tree(mid+1, end, X, depth+1, root);
        root->left = left;
        root->right = right;
        if(left != nullptr) {
            for(int j=0; j<d; ++j) {
                root->cmin[j] = std::min(root->cmin[j], left->cmin[j]);
                root->cmax[j] = std::max(root->cmax[j], left->cmax[j]);
            }
        }
        if(right != nullptr) {
            for(int j=0; j<d; ++j) {
                root->cmin[j] = std::min(root->cmin[j], right->cmin[j]);
                root->cmax[j] = std::max(root->cmax[j], right->cmax[j]);
            }
        }
        return root;
    }
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x128(%rsp)
movq %rsi, 0x120(%rsp)
movq %rdx, 0x118(%rsp)
movl %ecx, 0x114(%rsp)
movq %r8, 0x108(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x7240
movq %rax, 0x100(%rsp)
cmpq $0x0, 0x100(%rsp)
jne 0xc827
movq $0x0, 0x130(%rsp)
jmp 0xcd24
movq 0x100(%rsp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rsi
leaq 0x128(%rsp), %rdi
callq 0xcec0
movq %rax, 0xf0(%rsp)
cmpq $0x1, 0x100(%rsp)
jle 0xc90a
movq 0x128(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0x118(%rsp), %rax
movq %rax, 0x68(%rsp)
movl 0x114(%rsp), %eax
movl %eax, 0x74(%rsp)
movq 0x118(%rsp), %rdi
callq 0x4cd0
movq 0x68(%rsp), %rsi
movl %eax, %ecx
movl 0x74(%rsp), %eax
cltd
idivl %ecx
leaq 0xc8(%rsp), %rdi
callq 0xcfe0
movq 0xe8(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0xd8(%rsp), %rdx
movq 0xc8(%rsp), %rcx
movl 0xd0(%rsp), %r8d
callq 0xcf00
movl $0x50, %edi
callq 0x2180
movq %rax, 0x58(%rsp)
movq %rax, 0x50(%rsp)
movl 0x114(%rsp), %eax
movl %eax, 0x64(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0xd010
movq 0x58(%rsp), %rdi
movl 0x64(%rsp), %esi
movl (%rax), %edx
movq 0x108(%rsp), %rcx
callq 0xd020
jmp 0xc950
movq 0x50(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0x118(%rsp), %rdi
callq 0x4cd0
movl %eax, 0xb0(%rsp)
movq 0xc0(%rsp), %rdi
addq $0x20, %rdi
movslq 0xb0(%rsp), %rsi
callq 0x3e30
movq 0xc0(%rsp), %rax
addq $0x20, %rax
movq %rax, 0x40(%rsp)
movq 0x118(%rsp), %rdi
movq 0xc0(%rsp), %rax
movl 0x4(%rax), %esi
callq 0x3ab0
movq %rax, 0x48(%rsp)
movq 0x118(%rsp), %rdi
movq 0xc0(%rsp), %rax
movl 0x4(%rax), %esi
callq 0xd0c0
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq %rax, %rdx
callq 0xd090
movq 0xc0(%rsp), %rsi
addq $0x20, %rsi
movq 0xc0(%rsp), %rdi
addq $0x38, %rdi
callq 0xd0f0
movq 0x128(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x118(%rsp), %rdx
movl 0x114(%rsp), %ecx
addl $0x1, %ecx
movq 0xc0(%rsp), %r8
movq 0xa0(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0xc7c0
movq %rax, 0xa8(%rsp)
leaq 0xf0(%rsp), %rdi
movl $0x1, %esi
callq 0xcec0
movq %rax, 0x88(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x118(%rsp), %rdx
movl 0x114(%rsp), %ecx
addl $0x1, %ecx
movq 0xc0(%rsp), %r8
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0xc7c0
movq %rax, 0x90(%rsp)
movq 0xa8(%rsp), %rcx
movq 0xc0(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x90(%rsp), %rcx
movq 0xc0(%rsp), %rax
movq %rcx, 0x18(%rax)
cmpq $0x0, 0xa8(%rsp)
je 0xcc0c
movl $0x0, 0x7c(%rsp)
movl 0x7c(%rsp), %eax
cmpl 0xb0(%rsp), %eax
jge 0xcc0a
movq 0xc0(%rsp), %rdi
addq $0x20, %rdi
movslq 0x7c(%rsp), %rsi
callq 0x42a0
movq %rax, 0x20(%rsp)
movq 0xa8(%rsp), %rdi
addq $0x20, %rdi
movslq 0x7c(%rsp), %rsi
callq 0x42a0
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0xd3b0
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0xc0(%rsp), %rdi
addq $0x20, %rdi
movslq 0x7c(%rsp), %rsi
callq 0x42a0
movsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rax)
movq 0xc0(%rsp), %rdi
addq $0x38, %rdi
movslq 0x7c(%rsp), %rsi
callq 0x42a0
movq %rax, 0x30(%rsp)
movq 0xa8(%rsp), %rdi
addq $0x38, %rdi
movslq 0x7c(%rsp), %rsi
callq 0x42a0
movq 0x30(%rsp), %rdi
movq %rax, %rsi
callq 0xd3f0
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0xc0(%rsp), %rdi
addq $0x38, %rdi
movslq 0x7c(%rsp), %rsi
callq 0x42a0
movsd 0x38(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7c(%rsp)
jmp 0xcaf6
movq 0x50(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xb8(%rsp)
movl %eax, 0xb4(%rsp)
callq 0x2140
jmp 0xcd34
jmp 0xcc0c
cmpq $0x0, 0x90(%rsp)
je 0xcd14
movl $0x0, 0x78(%rsp)
movl 0x78(%rsp), %eax
cmpl 0xb0(%rsp), %eax
jge 0xcd12
movq 0xc0(%rsp), %rdi
addq $0x20, %rdi
movslq 0x78(%rsp), %rsi
callq 0x42a0
movq %rax, (%rsp)
movq 0x90(%rsp), %rdi
addq $0x20, %rdi
movslq 0x78(%rsp), %rsi
callq 0x42a0
movq (%rsp), %rdi
movq %rax, %rsi
callq 0xd3b0
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0xc0(%rsp), %rdi
addq $0x20, %rdi
movslq 0x78(%rsp), %rsi
callq 0x42a0
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rax)
movq 0xc0(%rsp), %rdi
addq $0x38, %rdi
movslq 0x78(%rsp), %rsi
callq 0x42a0
movq %rax, 0x10(%rsp)
movq 0x90(%rsp), %rdi
addq $0x38, %rdi
movslq 0x78(%rsp), %rsi
callq 0x42a0
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0xd3f0
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0xc0(%rsp), %rdi
addq $0x38, %rdi
movslq 0x78(%rsp), %rsi
callq 0x42a0
movsd 0x18(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0xcc23
jmp 0xcd14
movq 0xc0(%rsp), %rax
movq %rax, 0x130(%rsp)
movq 0x130(%rsp), %rax
addq $0x138, %rsp            # imm = 0x138
retq
movq 0xb8(%rsp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)