private FenwickTreeNode ParseArrayIntoFenwickTreeHelper(int[] array, int lower, int upper) { if (lower > upper) { return(null); } if (lower == upper) { return(new FenwickTreeNode { lower = lower, upper = upper, value = array[lower], }); } var node = new FenwickTreeNode { lower = lower, upper = upper, left = ParseArrayIntoFenwickTreeHelper(array, lower, (upper + lower) / 2), right = ParseArrayIntoFenwickTreeHelper(array, (upper + lower) / 2 + 1, upper), }; node.value = (node.left == null ? 0 : node.left.value) + (node.right == null ? 0 : node.right.value); return(node); }
private int QueryAndUpdateFenwickTree(int value, FenwickTreeNode head, int[] valueIndexArray, int currentEmptySlot) { var index = valueIndexArray[value]; var result = Query(head, 0, index); Update(head, index, 0); Update(head, currentEmptySlot, 1); valueIndexArray[value] = currentEmptySlot; return(result); }
private int Query(FenwickTreeNode head, int lower, int upper) { if (head == null) { return(0); } if (head.lower == lower && head.upper == upper) { return(head.value); } if (upper <= head.left.upper) { return(Query(head.left, lower, upper)); } else { return(Query(head.left, lower, head.left.upper) + Query(head.right, head.right.lower, upper)); } }
private void Update(FenwickTreeNode head, int index, int value) { if (head == null) { return; } if (head.upper == index && head.lower == index) { head.value = value; return; } if (index <= (head.upper + head.lower) / 2) { Update(head.left, index, value); } else { Update(head.right, index, value); } head.value = (head.left == null ? 0 : head.left.value) + (head.right == null ? 0 : head.right.value); }