PHP•count-of-range-sum/solution.php
class Solution {
function countRangeSum($nums, $lower, $upper) {
$count = class="syntax-number">0;
$presum = [class="syntax-number">0];
foreach ($nums as $num) {
$presum[] = $presum[count($presum) - class="syntax-number">1] + $num;
}
$count = $this->mergeSort($presum, $lower, $upper, class="syntax-number">0, count($presum) - class="syntax-number">1);
return $count;
}
function mergeSort(&$presum, $lower, $upper, $left, $right) {
if ($left >= $right) return class="syntax-number">0;
$mid = $left + intdiv($right - $left, class="syntax-number">2);
$count = $this->mergeSort($presum, $lower, $upper, $left, $mid) + $this->mergeSort($presum, $lower, $upper, $mid + class="syntax-number">1, $right);
$temp = [];
$p1 = $p2 = $p3 = $mid + class="syntax-number">1;
for ($p1 = $left, $right_start = $mid + class="syntax-number">1; $p1 <= $mid; $p1++) {
while ($p2 <= $right && $presum[$p2] - $presum[$p1] < $lower) $p2++;
while ($p3 <= $right && $presum[$p3] - $presum[$p1] <= $upper) $p3++;
$count += $p3 - $p2;
while ($right_start <= $right && $presum[$right_start] < $presum[$p1]) $temp[] = $presum[$right_start++];
$temp[] = $presum[$p1];
}
while ($right_start <= $right) $temp[] = $presum[$right_start++];
for ($i = $left, $j = class="syntax-number">0; $i <= $right; $i++, $j++) {
$presum[$i] = $temp[$j];
}
return $count;
}
}