我正在尝试解决任务: 给定一个功能。函数参数之一是数组。它可以是1维/ 2维或3维。 其余参数为:求和函数和中性数。将为0。 我需要根据传入数组构建段树(1D / 2D / 3D)并计算范围总和。 有人可以给我提示吗?
我写了一个构建2D片段树的函数。下面的代码:
function recursiveSegmentTree(array, fn, N) {
var t = new Array(array.length * 16);
//Building X2D segment tree
function build_Y(vx, lx, rx, vy, ly, ry, array){
if (ly == ry){
if (lx == rx){
t[vx][vy] = array[lx][ly];
}else{
t[vx][vy] = fn(t[2 * vx][vy], t[2 * vx + 1][vy]);
}
}else{
let vmiddleY = Math.floor((ry + ly) / 2);
build_Y(vx, lx, rx, 2 * vy, ly, vmiddleY, array);
build_Y(vx, lx, rx, 2 * vy + 1, vmiddleY + 1, ry, array);
t[vx][vy] = fn(t[vx][2 * vy], t[vx][2 * vy + 1]);
}
}
function build_X(vx, lx, rx, array){
if (lx != rx){
let vmiddleX = Math.floor((rx + lx) / 2);
build_X(2 * vx, lx, vmiddleX, array);
build_X(2 * vx + 1, vmiddleX + 1, rx, array);
}
build_Y(vx, lx, rx, 1, 0, array.length - 1, array);
}
//Calculating sum
function finalQuery(pos, start, end, x1, x2, node, array, N){
if (x2 < start || x1 > end){
return N;
}
if (x1 <= start && end <= x2){
return t[node][pos];
}
let mid = Math.floor((start + end) / 2);
let p1 = finalQuery(2 * pos, start, mid, x1, x2, node, array, N);
let p2 = finalQuery(2 * pos + 1, mid + 1, end, x1, x2, node, array, N);
let result = fn(p1, p2);
return fn(N, result);
}
function query(pos, start, end, y1, y2, x1, x2, array, N){
if (y2 < start || end < y1){
return 0;
}
if (y1 <= start && end <= y2) {
return finalQuery(1, 0, 3, x1, x2, pos, array, N);
}
let mid = Math.floor((start + end) / 2);
let p1 = query(2 * pos, start, mid, y1, y2, x1, x2, array, N);
let p2 = query(2 * pos + 1, mid + 1, end, y1, y2, x1, x2, array, N);
let result = fn(p1, p2);
return fn(N, result);
}
for (let i = 0; i < (array.length * 16); i++){
t[i] = new Array(array.length * 16);
}
return function (from, to) {
if (from < 0 || array.length < to){
throw new Error("Out of range");
}
if (to < from) {
throw new Error("From is greater");
}
if (from == to) { return N; }
let result = N;
if (Array.isArray(array[0]) == false){
array.slice(from, to).forEach((arr) => {
if (!Array.isArray(arr)) {
result += arr;
}
else {
result += fn(result, arr);
}
});
} else if (Array.isArray(array[0]) == true){
build_X(1, 0, array.length - 1, array);
console.log(t);
result = query(1, 0, array.length - 1, from, to - 1, from, to - 1, array, N);
}
return result;
};
};