2
* @param {number[]} nums5
* @param {number} right8
var rangeSum = function (nums, n, left, right) {11
var prefix = [nums[0]];12
function buildPrefix() {13
for (var i = 1; i < len; i++) {14
prefix[i] = prefix[i - 1] + nums[i];20
function countUnderSum(sum, cb) {26
let wholeSubSum = prefix[right] - (left === 0 ? 0 : prefix[left - 1]);27
if (wholeSubSum <= sum) {28
count += right - left + 1;29
cb && cb(left, right);31
while (wholeSubSum > sum) {33
wholeSubSum -= nums[left];39
count += right - left + 1;40
cb && cb(left, right);48
function calSubArraySumByRange(i, j) {49
var windowLen = j - i + 1;51
while (windowLen > 0) {52
sum += nums[j] * windowLen;59
function calSum(count) {60
var lowSum = findTheLowestSumThatSatisfyTheSpecficCount(count);62
countUnderSum(lowSum, (i, j) => {63
sum += calSubArraySumByRange(i, j);66
//This line is used to deal with some same value cases67
//Such as if the low value is 9, and we have 9 subarrays of which low value68
//is 9. But the count is 8, so we must remove one of it.69
return sum - (countUnderSum(lowSum) - count) * lowSum;72
function findTheLowestSumThatSatisfyTheSpecficCount(count) {74
var r = prefix[len - 1];76
var mid = Math.floor((l + r) / 2);77
if (countUnderSum(mid) < count) {87
return (calSum(right) - calSum(left - 1)) % (Math.pow(10, 9) + 7);