// File: /workspace/github_cpp_makefile_star2_O1/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 0x166fa4
movq %r9, %r14
movq %rsi, %r15
movq %rdi, %r12
movq 0x28(%rsi), %rdi
movq %rbx, %rsi
callq 0x1637b8
movsd %xmm0, (%rsp)
cmpl $0x2, 0xc(%rbx)
je 0x166fa4
movl 0xc(%rbx), %edx
testl %edx, %edx
je 0x166b59
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), %edx
cmpq %rdx, %rax
jb 0x166b1c
movq 0x28(%rbx), %rsi
movq %r14, %rdi
callq 0x165801
movq 0x28(%r15), %rsi
leaq 0xc(%rsp), %rcx
movq %r12, %rdi
movq %rbx, %rdx
callq 0x164af0
ucomisd (%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x166bcb
testl %eax, %eax
je 0x166bc4
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), %ecx
cmpq %rcx, %rax
jb 0x166b89
movsd %xmm0, (%rsp)
jmp 0x166c0e
testl %eax, %eax
je 0x166c0e
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 0x166bd1
testq %r14, %r14
je 0x166cb4
movq %r14, %rdi
callq 0x166a5b
ucomisd (%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x166c71
testl %eax, %eax
je 0x166c6a
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), %ecx
cmpq %rcx, %rax
jb 0x166c2f
movsd %xmm0, (%rsp)
jmp 0x166cb4
testl %eax, %eax
je 0x166cb4
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 0x166c77
cmpl $0x0, 0x4(%r12)
je 0x166eb4
sarl $0x4, 0x10(%rsp)
xorl %r13d, %r13d
xorl %ebp, %ebp
movq 0x28(%r15), %rsi
movq %r12, %rdi
movq %rbx, %rdx
testb $0x1, %bpl
jne 0x166ce1
callq 0x164ca6
jmp 0x166ce6
callq 0x164bb0
movq 0x28(%r15), %rsi
movq %r12, %rdi
movq %rbx, %rdx
leaq 0xc(%rsp), %rcx
callq 0x164af0
ucomisd (%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x166d4f
xorl %r13d, %r13d
testl %eax, %eax
je 0x166d48
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), %ecx
cmpq %rcx, %rax
jb 0x166d0d
movsd %xmm0, (%rsp)
jmp 0x166d95
testl %eax, %eax
je 0x166d92
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 0x166d55
incl %r13d
testq %r14, %r14
je 0x166e4c
cmpl 0x10(%rsp), %r13d
jb 0x166e4c
movq %r14, %rdi
callq 0x166a5b
ucomisd (%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x166e06
xorl %r13d, %r13d
testl %eax, %eax
je 0x166dff
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), %ecx
cmpq %rcx, %rax
jb 0x166dc4
movsd %xmm0, (%rsp)
jmp 0x166e4c
xorl %r13d, %r13d
testl %eax, %eax
je 0x166e4c
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 0x166e0f
movl 0xc(%rsp), %eax
xorl %edx, %edx
divl 0x14(%rsp)
testl %edx, %edx
jne 0x166ea7
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x16360e
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x163573
movsd %xmm0, (%rsp)
cmpl $0x0, 0xc(%rbx)
je 0x166ea7
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), %xmm0
movupd %xmm0, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x166e7f
incl %ebp
cmpl 0x4(%r12), %ebp
jb 0x166cca
testq %r14, %r14
je 0x166f5b
movq %r14, %rdi
callq 0x166a5b
ucomisd (%rsp), %xmm0
movl 0xc(%rbx), %eax
jbe 0x166f18
testl %eax, %eax
je 0x166f5b
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 0x166ed9
jmp 0x166f5b
testl %eax, %eax
je 0x166f5b
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 0x166f1e
cmpl $0x0, 0xc(%rbx)
je 0x166fa0
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 0x166f63
movl 0xc(%rsp), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq