benchmark_type mcss_bench() { long n = pasl::util::cmdline::parse_or_default_long("n", 1l<<20); sparray* inp = new sparray(0); value_type* outp = new value_type; auto init = [=] { *inp = gen_random_sparray(n); }; auto bench = [=] { *outp = mcss(*inp); }; auto output = [=] { std::cout << "result " << *outp << std::endl; }; auto destroy = [=] { delete inp; delete outp; }; return make_benchmark(init, bench, output, destroy); }
sumnode mcss(int *a, int left, int right) { sumnode leftsum, rightsum, mtlsum, mtrsum, thissum, tempsum; if (right - left <= 1) { thissum.sum = a[left]; thissum.left = left; thissum.right = right; return thissum; } else { leftsum = mcss(a, left, (right + left) / 2); rightsum = mcss(a, (right + left) / 2, right); if (leftsum.right == rightsum.left) { thissum.left = leftsum.left; thissum.right = rightsum.right; thissum.sum = leftsum.sum + rightsum.sum; } else { mtlsum.sum = 0; mtlsum.left = mtlsum.right = (left + right) / 2; mtrsum.sum = 0; mtrsum.left = mtrsum.right = (left + right) / 2; tempsum.sum = 0; for (int i = (left + right) / 2 - 1; i >= leftsum.left ; --i) { tempsum.sum += a[i]; if (tempsum.sum > mtlsum.sum) { mtlsum.sum = tempsum.sum; mtlsum.left = i; } } tempsum.sum = 0; for (int i = (left + right) / 2; i < rightsum.right ; ++i) { tempsum.sum += a[i]; if (tempsum.sum > mtrsum.sum) { mtrsum.sum = tempsum.sum; mtrsum.right = i + 1; } } thissum.sum = 0; thissum.left = thissum.right = (left + right) / 2; if (mtlsum.sum > 0) { thissum.sum += mtlsum.sum; thissum.left = mtlsum.left; } if (mtrsum.sum > 0) { thissum.sum += mtrsum.sum; thissum.right = mtrsum.right; } } if (thissum.sum > leftsum.sum) return (thissum.sum > rightsum.sum) ? thissum : rightsum; else return (leftsum.sum > rightsum.sum) ? leftsum : rightsum; } }