public void Update(MaximumSumQueryObject updatedLeftChild, MaximumSumQueryObject updatedRightChild) { Sum = GetCombinedSum(updatedLeftChild, updatedRightChild); MaximumSum = GetCombinedMaximumSum(updatedLeftChild, updatedRightChild); MaximumLeftStartingSum = GetCombinedMaximumLeftStartingSum(updatedLeftChild, updatedRightChild); MaximumRightStartingSum = GetCombinedMaximumRightStartingSum(updatedLeftChild, updatedRightChild); }
} // [ ... <-] public MaximumSumQueryObject Combine(MaximumSumQueryObject rightAdjacentObject) => new MaximumSumQueryObject { SegmentStartIndex = SegmentStartIndex, SegmentEndIndex = rightAdjacentObject.SegmentEndIndex, Sum = GetCombinedSum(this, rightAdjacentObject), MaximumSum = GetCombinedMaximumSum(this, rightAdjacentObject), MaximumLeftStartingSum = GetCombinedMaximumLeftStartingSum(this, rightAdjacentObject), MaximumRightStartingSum = GetCombinedMaximumRightStartingSum(this, rightAdjacentObject) };
private void Build(int treeArrayIndex, int segmentStartIndex, int segmentEndIndex) { if (segmentStartIndex == segmentEndIndex) { _treeArray[treeArrayIndex] = new MaximumSumQueryObject(segmentStartIndex, _sourceArray[segmentStartIndex]); return; } int leftChildTreeArrayIndex = 2 * treeArrayIndex + 1; int rightChildTreeArrayIndex = leftChildTreeArrayIndex + 1; Build(leftChildTreeArrayIndex, segmentStartIndex, (segmentStartIndex + segmentEndIndex) / 2); Build(rightChildTreeArrayIndex, (segmentStartIndex + segmentEndIndex) / 2 + 1, segmentEndIndex); _treeArray[treeArrayIndex] = _treeArray[leftChildTreeArrayIndex].Combine(_treeArray[rightChildTreeArrayIndex]); }
private void Build(int treeArrayIndex, int segmentStartIndex, int segmentEndIndex) { if (segmentStartIndex == segmentEndIndex) { _treeArray[treeArrayIndex] = new MaximumSumQueryObject(_sourceArray[segmentStartIndex]); return; } int leftChildTreeArrayIndex = 2 * treeArrayIndex + 1; int rightChildTreeArrayIndex = leftChildTreeArrayIndex + 1; int leftChildSegmentEndIndex = (segmentStartIndex + segmentEndIndex) / 2; Build(leftChildTreeArrayIndex, segmentStartIndex, leftChildSegmentEndIndex); Build(rightChildTreeArrayIndex, leftChildSegmentEndIndex + 1, segmentEndIndex); _treeArray[treeArrayIndex] = _treeArray[leftChildTreeArrayIndex].Combine(_treeArray[rightChildTreeArrayIndex]); }
public MaximumSumQueryObject Combine(MaximumSumQueryObject rightAdjacentValue) => new MaximumSumQueryObject { // The sum is just the sum of both. Sum = Sum + rightAdjacentValue.Sum, // The maximum sum either intersects both segments, or is entirely in one. MaximumSum = Math.Max( MaximumRightStartingSum + rightAdjacentValue.MaximumLeftStartingSum, Math.Max(MaximumSum, rightAdjacentValue.MaximumSum)), // The maximum left starting sum starts at the left, and may or may not cross into the right. MaximumLeftStartingSum = Math.Max( Sum + rightAdjacentValue.MaximumLeftStartingSum, MaximumLeftStartingSum), // The maximum right starting sum starts at the right, and may or may not cross into the left. MaximumRightStartingSum = Math.Max( rightAdjacentValue.Sum + MaximumRightStartingSum, rightAdjacentValue.MaximumRightStartingSum) };
private static int GetCombinedMaximumRightStartingSum(MaximumSumQueryObject leftAdjacentObject, MaximumSumQueryObject rightAdjacentObject) // The maximum right starting sum starts at the right, and may or may not cross into the left. => Math.Max( rightAdjacentObject.Sum + leftAdjacentObject.MaximumRightStartingSum, rightAdjacentObject.MaximumRightStartingSum);
private static int GetCombinedMaximumSum(MaximumSumQueryObject leftAdjacentObject, MaximumSumQueryObject rightAdjacentObject) // The maximum sum either intersects both segments, or is entirely in one. => Math.Max( leftAdjacentObject.MaximumRightStartingSum + rightAdjacentObject.MaximumLeftStartingSum, Math.Max(leftAdjacentObject.MaximumSum, rightAdjacentObject.MaximumSum));
private static int GetCombinedSum(MaximumSumQueryObject leftAdjacentObject, MaximumSumQueryObject rightAdjacentObject) // The sum is just the sum of both. => leftAdjacentObject.Sum + rightAdjacentObject.Sum;
private static int GetCombinedMaximumRightStartingSum(MaximumSumQueryObject leftAdjacentObject, MaximumSumQueryObject rightAdjacentObject) // The maximum right starting sum starts at the right, and may or may not cross into the left. => Math.Max( rightAdjacentObject.Sum + leftAdjacentObject.MaximumRightStartingSum, rightAdjacentObject.MaximumRightStartingSum);
private static int GetCombinedMaximumSum(MaximumSumQueryObject leftAdjacentObject, MaximumSumQueryObject rightAdjacentObject) // The maximum sum either intersects both segments, or is entirely in one. => Math.Max( leftAdjacentObject.MaximumRightStartingSum + rightAdjacentObject.MaximumLeftStartingSum, Math.Max(leftAdjacentObject.MaximumSum, rightAdjacentObject.MaximumSum));
private static int GetCombinedSum(MaximumSumQueryObject leftAdjacentObject, MaximumSumQueryObject rightAdjacentObject) // The sum is just the sum of both. => leftAdjacentObject.Sum + rightAdjacentObject.Sum;
public void Update(MaximumSumQueryObject updatedLeftChild, MaximumSumQueryObject updatedRightChild) { Sum = GetCombinedSum(updatedLeftChild, updatedRightChild); MaximumSum = GetCombinedMaximumSum(updatedLeftChild, updatedRightChild); MaximumLeftStartingSum = GetCombinedMaximumLeftStartingSum(updatedLeftChild, updatedRightChild); MaximumRightStartingSum = GetCombinedMaximumRightStartingSum(updatedLeftChild, updatedRightChild); }
private int MaximumRightStartingSum { get; set; } // [ ... <-] public MaximumSumQueryObject Combine(MaximumSumQueryObject rightAdjacentObject) => new MaximumSumQueryObject() { SegmentStartIndex = SegmentStartIndex, SegmentEndIndex = rightAdjacentObject.SegmentEndIndex, Sum = GetCombinedSum(this, rightAdjacentObject), MaximumSum = GetCombinedMaximumSum(this, rightAdjacentObject), MaximumLeftStartingSum = GetCombinedMaximumLeftStartingSum(this, rightAdjacentObject), MaximumRightStartingSum = GetCombinedMaximumRightStartingSum(this, rightAdjacentObject) };