// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/rcut.cpp
// Function: mc_solve_cc_adv(mc_opt_t const*, mc_g_t const*, mc_svaux_t*, unsigned int, unsigned int, mc_clus_t*)
uint32_t mc_solve_cc_adv(const mc_opt_t *opt, const mc_g_t *mg, mc_svaux_t *b, uint32_t cc_off, uint32_t cc_size, mc_clus_t *bc)
{
	uint32_t j, k, n_iter = 0, flush = opt->max_iter * 50, n_skip, n_skip_flush = opt->n_perturb/16;
	t_w_t sc_opt = -(1<<30), sc;///problem-w
	b->cc_off = cc_off, b->cc_size = cc_size;
	if (b->cc_size < 2) return 0;
	sc_opt = mc_init_spin(mg->e, b);
	// print_sc(opt, mg, b, sc_opt, n_iter);
	if (b->cc_size == 2) return 0;
	for (j = 0; j < b->cc_size; ++j) {///backup s and z in s_opt and z_opt
		b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]]; ///hap status of each unitig
		b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]]; ///z[0]: positive weight; z[1]: positive weight
	}
	// renew_mc_clus_t(bc, b->cc_node, b->cc_size);
	renew_mc_clus_t_adv(bc, b->cc_node, b->cc_size);
	// fprintf(stderr, "\ncc_size: %u, cc_off: %u\n", b->cc_size, b->cc_off);
	// print_sc(opt, mg->e, b, sc_opt, n_iter);
	sc = mc_optimize_local(opt, mg->e, b, &n_iter);
	if (sc > sc_opt) {
		for (j = 0; j < b->cc_size; ++j) {
			b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
			b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
		}
		sc_opt = sc;
	} else {
		for (j = 0; j < b->cc_size; ++j) {
			b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
			b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
		}
	}
    // print_mc_node(mg->e, b, 36880);
	// print_sc(opt, mg, b, sc_opt, n_iter);
	// mc_reset_z_debug(mg->e, b);
	// print_sc(opt, mg->e, b, sc_opt, n_iter);
	// fprintf(stderr, "\ncc_size: %u, cc_off: %u\n", b->cc_size, b->cc_off);
	
	if(bc) {
		sc = mc_clus_cc(bc);
		if (sc > sc_opt) {
			for (j = 0; j < b->cc_size; ++j) {
				b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
		} else {
			for (j = 0; j < b->cc_size; ++j) {
				b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
				b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
			}
		}
	}
	
	for (k = n_skip = 0; k < (uint32_t)opt->n_perturb; ++k) {
		if (k&1) mc_perturb(opt, mg->e, b);
		else mc_perturb_node(opt, mg->e, b, 3);
		sc = mc_optimize_local(opt, mg->e, b, &n_iter);
		// if((k%256) == 0) fprintf(stderr, "(%u) sc_opt::%f, sc::%f, flush::%u, n_iter::%u\n", k, sc_opt, sc, flush, n_iter);
		if (sc > sc_opt) {
			for (j = 0; j < b->cc_size; ++j) {
				b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc; n_skip = 0;
			// print_sc(opt, mg, b, sc_opt, n_iter);
		} else {
			for (j = 0; j < b->cc_size; ++j) {
				b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
				b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
			}
			n_skip++;
		}
		if(n_skip >= n_skip_flush && bc) {
			sc = mc_clus_cc(bc);
			if (sc > sc_opt) {
				for (j = 0; j < b->cc_size; ++j) {
					b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
					b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
				}
				sc_opt = sc;
			} else {
				for (j = 0; j < b->cc_size; ++j) {
					b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
					b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
				}
			}
			n_skip = 0;
		}

		if((n_iter%flush) == 0) {
			mc_reset_z(mg->e, b);
			sc = mc_score(mg->e, b);

			for (j = 0; j < b->cc_size; ++j) {
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
		}
	}
	if(bc) {
		sc = mc_clus_cc(bc);
		if (sc > sc_opt) {
			for (j = 0; j < b->cc_size; ++j) {
				b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
		} else {
			for (j = 0; j < b->cc_size; ++j) {
				b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
				b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
			}
		}
	}

	// if(bc) {
	// 	bc->dbg = 1;
	// 	mc_clus_cc(bc);
	// 	bc->dbg = 0;
	// }

	for (j = 0; j < b->cc_size; ++j)
	{
		b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
		b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
	}
	// exit(1);
	return n_iter;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movl $0x0, 0xc(%rsp)
imull $0x32, (%rdi), %eax
movl %eax, 0x14(%rsp)
movl 0x4(%rdi), %eax
leal 0xf(%rax), %edx
testl %eax, %eax
cmovnsl %eax, %edx
movl %edx, 0x10(%rsp)
movl %ecx, 0x8(%rbx)
movl %r8d, 0xc(%rbx)
xorl %ebp, %ebp
cmpl $0x2, %r8d
jb 0x16d9d0
movq %r9, %r14
movq %rsi, %r15
movq %rdi, %r12
movq 0x28(%rsi), %rdi
movq %rbx, %rsi
callq 0x16a16a
movl 0xc(%rbx), %edx
testl %edx, %edx
je 0x16d510
cmpl $0x2, %edx
je 0x16d9d0
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movups (%rdx,%rcx), %xmm1
movups %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %edx
cmpq %rdx, %rax
jb 0x16d4d5
movsd %xmm0, (%rsp)
movq 0x28(%rbx), %rsi
movq %r14, %rdi
callq 0x16c1ce
movq 0x28(%r15), %rsi
leaq 0xc(%rsp), %rcx
movq %r12, %rdi
movq %rbx, %rdx
callq 0x16b4a4
movsd (%rsp), %xmm1
ucomisd %xmm1, %xmm0
movl 0xc(%rbx), %eax
jbe 0x16d58c
testl %eax, %eax
je 0x16d5d1
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d54d
jmp 0x16d5d3
testl %eax, %eax
je 0x16d5d9
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d592
jmp 0x16d5db
xorl %ecx, %ecx
movapd %xmm0, %xmm1
jmp 0x16d5db
xorl %ecx, %ecx
testq %r14, %r14
je 0x16d697
movq %r14, %rdi
movsd %xmm1, (%rsp)
callq 0x16d41a
movsd (%rsp), %xmm1
ucomisd %xmm1, %xmm0
movl 0xc(%rbx), %eax
jbe 0x16d648
testl %eax, %eax
je 0x16d68d
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d609
jmp 0x16d68f
testl %eax, %eax
je 0x16d695
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d64e
jmp 0x16d697
xorl %ecx, %ecx
movapd %xmm0, %xmm1
jmp 0x16d697
xorl %ecx, %ecx
cmpl $0x0, 0x4(%r12)
je 0x16d8d5
sarl $0x4, 0x10(%rsp)
xorl %r13d, %r13d
xorl %ebp, %ebp
movsd %xmm1, (%rsp)
movq 0x28(%r15), %rsi
testb $0x1, %bpl
jne 0x16d6d0
movsd 0x10(%r12), %xmm0
movq %rsi, %rdi
movq %rbx, %rsi
callq 0x16b657
jmp 0x16d6db
movq %r12, %rdi
movq %rbx, %rdx
callq 0x16b557
movq 0x28(%r15), %rsi
movq %r12, %rdi
movq %rbx, %rdx
leaq 0xc(%rsp), %rcx
callq 0x16b4a4
movsd (%rsp), %xmm1
ucomisd %xmm1, %xmm0
movl 0xc(%rbx), %eax
jbe 0x16d749
xorl %r13d, %r13d
testl %eax, %eax
je 0x16d78e
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d70a
jmp 0x16d790
testl %eax, %eax
je 0x16d796
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d74f
jmp 0x16d798
xorl %ecx, %ecx
movapd %xmm0, %xmm1
jmp 0x16d79b
xorl %ecx, %ecx
incl %r13d
testq %r14, %r14
je 0x16d864
cmpl 0x10(%rsp), %r13d
jb 0x16d864
movq %r14, %rdi
movsd %xmm1, (%rsp)
callq 0x16d41a
movsd (%rsp), %xmm1
ucomisd %xmm1, %xmm0
movl 0xc(%rbx), %eax
jbe 0x16d816
xorl %r13d, %r13d
testl %eax, %eax
je 0x16d85e
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d7d7
jmp 0x16d868
xorl %r13d, %r13d
testl %eax, %eax
je 0x16d862
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d81f
jmp 0x16d864
xorl %ecx, %ecx
jmp 0x16d868
xorl %ecx, %ecx
movapd %xmm1, %xmm0
movl 0xc(%rsp), %eax
xorl %edx, %edx
divl 0x14(%rsp)
testl %edx, %edx
jne 0x16d8c2
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x169f7d
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x169ee2
cmpl $0x0, 0xc(%rbx)
je 0x16d8c0
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d896
jmp 0x16d8c2
xorl %ecx, %ecx
incl %ebp
movapd %xmm0, %xmm1
cmpl 0x4(%r12), %ebp
jb 0x16d6ad
jmp 0x16d8d9
movapd %xmm1, %xmm0
testq %r14, %r14
je 0x16d989
movq %r14, %rdi
movsd %xmm0, (%rsp)
callq 0x16d41a
ucomisd (%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x16d942
testl %eax, %eax
je 0x16d9cc
xorl %eax, %eax
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm0
movupd %xmm0, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d903
jmp 0x16d989
testl %eax, %eax
je 0x16d9cc
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d94c
testl %ecx, %ecx
je 0x16d9cc
xorl %eax, %eax
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x16d98f
movl 0xc(%rsp), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq