// File: fpavetic[P]lcskpp/lcskpp.cpp
// Function: fill_lcskpp_reconstruction(std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>> const&, int, std::vector<int, std::allocator<int>> const&, int, int, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>*)
static void fill_lcskpp_reconstruction(
    const vector<pair<int, int> >& matches,
    const int k,
    const vector<int>& prev_idx,
    const int last_idx,
    const int lcskpp_len,
    vector<pair<int, int> >* lcskpp_recon) {
  assert(lcskpp_recon != NULL);
  lcskpp_recon->clear();
  lcskpp_recon->reserve(lcskpp_len);

  for (int i = last_idx; i != -1; i = prev_idx[i]) {
    int r = matches[i].first+k-1;
    int c = matches[i].second+k-1;

    if (prev_idx[i] == -1 || 
        (matches[prev_idx[i]].first + k <= matches[i].first &&
         matches[prev_idx[i]].second + k <= matches[i].second)) {
      // Taking the entire match ...
      for (int j = 0; j < k; ++j, --r, --c) {
        lcskpp_recon->push_back(make_pair(r, c));
      }
    } else { 
      // ... otherwise it is a continuation. Only the
      // difference is taken.
      int curr = i;
      int prev = prev_idx[i];

      int curr_secondary_diag = 
        (matches[curr].first + matches[curr].second) / 2;
      int prev_secondary_diag = 
        (matches[prev].first + matches[prev].second) / 2;
      assert(prev_secondary_diag < curr_secondary_diag);

      for (int j = prev_secondary_diag; 
           j < curr_secondary_diag; ++j, --r, --c) {
        lcskpp_recon->push_back(make_pair(r, c));
      }
    }
  }

  reverse(lcskpp_recon->begin(), lcskpp_recon->end());
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0xa0(%rsp)
movl %esi, 0x9c(%rsp)
movq %rdx, 0x90(%rsp)
movl %ecx, 0x8c(%rsp)
movl %r8d, 0x88(%rsp)
movq %r9, 0x80(%rsp)
cmpq $0x0, 0x80(%rsp)
je 0x6fe2
jmp 0x7001
leaq 0xb46b(%rip), %rdi      # 0x12454
leaq 0xb0c8(%rip), %rsi      # 0x120b8
movl $0x79, %edx
leaq 0xb46d(%rip), %rcx      # 0x12469
callq 0x20f0
movq 0x80(%rsp), %rdi
callq 0x76e0
movq 0x80(%rsp), %rdi
movslq 0x88(%rsp), %rsi
callq 0xc290
movl 0x8c(%rsp), %eax
movl %eax, 0x7c(%rsp)
cmpl $-0x1, 0x7c(%rsp)
je 0x7307
movq 0xa0(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0x7440
movl (%rax), %eax
addl 0x9c(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x78(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0x7440
movl 0x4(%rax), %eax
addl 0x9c(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x74(%rsp)
movq 0x90(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0xc3a0
cmpl $-0x1, (%rax)
je 0x714b
movq 0xa0(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x90(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0xc3a0
movq 0x28(%rsp), %rdi
movslq (%rax), %rsi
callq 0x7440
movl (%rax), %eax
addl 0x9c(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0x7440
movq %rax, %rcx
movl 0x34(%rsp), %eax
cmpl (%rcx), %eax
jg 0x71b8
movq 0xa0(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x90(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0xc3a0
movq 0x18(%rsp), %rdi
movslq (%rax), %rsi
callq 0x7440
movl 0x4(%rax), %eax
addl 0x9c(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0x7440
movq %rax, %rcx
movl 0x24(%rsp), %eax
cmpl 0x4(%rcx), %eax
jg 0x71b8
movl $0x0, 0x70(%rsp)
movl 0x70(%rsp), %eax
cmpl 0x9c(%rsp), %eax
jge 0x71b3
movq 0x80(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x74(%rsp), %rsi
callq 0xc3c0
movq 0x10(%rsp), %rdi
movq %rax, 0x68(%rsp)
leaq 0x68(%rsp), %rsi
callq 0x7860
movl 0x70(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x70(%rsp)
movl 0x78(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x78(%rsp)
movl 0x74(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x7153
jmp 0x72e8
movl 0x7c(%rsp), %eax
movl %eax, 0x64(%rsp)
movq 0x90(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0xc3a0
movl (%rax), %eax
movl %eax, 0x60(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x64(%rsp), %rsi
callq 0x7440
movl (%rax), %eax
movl %eax, 0x8(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x64(%rsp), %rsi
callq 0x7440
movq %rax, %rcx
movl 0x8(%rsp), %eax
addl 0x4(%rcx), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x5c(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x60(%rsp), %rsi
callq 0x7440
movl (%rax), %eax
movl %eax, 0xc(%rsp)
movq 0xa0(%rsp), %rdi
movslq 0x60(%rsp), %rsi
callq 0x7440
movq %rax, %rcx
movl 0xc(%rsp), %eax
addl 0x4(%rcx), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x58(%rsp)
movl 0x58(%rsp), %eax
cmpl 0x5c(%rsp), %eax
jge 0x7264
jmp 0x7283
leaq 0xb28e(%rip), %rdi      # 0x124f9
leaq 0xae46(%rip), %rsi      # 0x120b8
movl $0x92, %edx
leaq 0xb1eb(%rip), %rcx      # 0x12469
callq 0x20f0
movl 0x58(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
cmpl 0x5c(%rsp), %eax
jge 0x72e6
movq 0x80(%rsp), %rax
movq %rax, (%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x74(%rsp), %rsi
callq 0xc3c0
movq (%rsp), %rdi
movq %rax, 0x4c(%rsp)
leaq 0x4c(%rsp), %rsi
callq 0x7860
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
movl 0x78(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x78(%rsp)
movl 0x74(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x728b
jmp 0x72e8
jmp 0x72ea
movq 0x90(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
callq 0xc3a0
movl (%rax), %eax
movl %eax, 0x7c(%rsp)
jmp 0x702e
movq 0x80(%rsp), %rdi
callq 0x7950
movq %rax, 0x40(%rsp)
movq 0x80(%rsp), %rdi
callq 0x7980
movq %rax, 0x38(%rsp)
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0xc3f0
addq $0xa8, %rsp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)