// File: /workspace/github_cpp_makefile_star2_O2/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
movq %rsi, %r15
andl $0x0, 0x4(%rsp)
imull $0x32, (%rdi), %eax
movl %eax, 0x14(%rsp)
movl 0x4(%rdi), %eax
pushq $0x10
popq %rsi
cltd
idivl %esi
movl %eax, 0x10(%rsp)
movl %ecx, 0x8(%rbx)
movl %r8d, 0xc(%rbx)
xorl %r13d, %r13d
cmpl $0x2, %r8d
jb 0x129395
movq %r9, %r14
movq %rdi, %r12
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x125a9f
movl 0xc(%rbx), %edx
cmpl $0x2, %edx
je 0x129395
xorl %eax, %eax
movl %edx, %ecx
cmpq %rcx, %rax
jae 0x128f6a
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), %edx
jmp 0x128f29
movq 0x28(%rbx), %rsi
movq %r14, %rdi
movsd %xmm0, 0x8(%rsp)
callq 0x12790a
movq 0x28(%r15), %rsi
leaq 0x4(%rsp), %rcx
movq %r12, %rdi
movq %rbx, %rdx
callq 0x126d5e
movsd 0x8(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
jbe 0x128fdd
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x129020
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
jmp 0x128f9e
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x12901c
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
jmp 0x128fdd
movapd %xmm1, %xmm0
testq %r14, %r14
je 0x1290c7
movq %r14, %rdi
movsd %xmm0, 0x8(%rsp)
callq 0x128e76
movsd 0x8(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
jbe 0x129084
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x1290c7
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
jmp 0x129045
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x1290c3
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
jmp 0x129084
movapd %xmm1, %xmm0
xorl %r13d, %r13d
xorl %ebp, %ebp
cmpl 0x4(%r12), %r13d
movsd %xmm0, 0x8(%rsp)
jae 0x1292b2
movq 0x28(%r15), %rsi
movq %r12, %rdi
movq %rbx, %rdx
testb $0x1, %r13b
jne 0x1290f4
callq 0x126e6c
jmp 0x1290f9
callq 0x126e09
movq 0x28(%r15), %rsi
movq %r12, %rdi
movq %rbx, %rdx
leaq 0x4(%rsp), %rcx
callq 0x126d5e
movsd 0x8(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
ja 0x129152
jmp 0x129193
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 0x12911d
xorl %ebp, %ebp
jmp 0x1291a1
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 0x12915e
incl %ebp
movapd %xmm1, %xmm0
testq %r14, %r14
je 0x129258
cmpl 0x10(%rsp), %ebp
jb 0x129258
movq %r14, %rdi
movsd %xmm0, 0x8(%rsp)
callq 0x128e76
movsd 0x8(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
jbe 0x12920f
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x12924e
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
jmp 0x1291d0
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x129252
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
jmp 0x12920f
xorl %ebp, %ebp
jmp 0x129258
xorl %ebp, %ebp
movapd %xmm1, %xmm0
movl 0x4(%rsp), %eax
xorl %edx, %edx
divl 0x14(%rsp)
testl %edx, %edx
je 0x12926e
incl %r13d
jmp 0x1290cc
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x1258d9
movq 0x28(%r15), %rdi
movq %rbx, %rsi
callq 0x12584f
xorl %eax, %eax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x129266
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
jmp 0x129288
testq %r14, %r14
je 0x12934d
movq %r14, %rdi
callq 0x128e76
ucomisd 0x8(%rsp), %xmm0
jbe 0x12930c
xorl %eax, %eax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x12934d
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
jmp 0x1292cd
xorl %eax, %eax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x12934d
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
jmp 0x12930e
xorl %eax, %eax
movl %ecx, %ecx
cmpq %rcx, %rax
jae 0x129390
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
jmp 0x12934f
movl 0x4(%rsp), %r13d
movl %r13d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq