Пример #1
0
    private void Build(int treeArrayIndex, int segmentStartIndex, int segmentEndIndex)
    {
        if (segmentStartIndex == segmentEndIndex)
        {
            _treeArray[treeArrayIndex] = new MaximumSumQueryValue(_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]);
    }
Пример #2
0
    public MaximumSumQueryValue Combine(MaximumSumQueryValue rightAdjacentValue)
        => new MaximumSumQueryValue
        {
            // 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)
        };