public SecondMaximumQueryObject Combine(SecondMaximumQueryObject rightAdjacentObject) => new SecondMaximumQueryObject { SegmentStartIndex = SegmentStartIndex, SegmentEndIndex = rightAdjacentObject.SegmentEndIndex, Maximum = GetCombinedMaximum(this, rightAdjacentObject), SecondMaximum = GetCombinedSecondMaximum(this, rightAdjacentObject) };
private void Build(int treeArrayIndex, int segmentStartIndex, int segmentEndIndex) { if (segmentStartIndex == segmentEndIndex) { _treeArray[treeArrayIndex] = new SecondMaximumQueryObject(segmentStartIndex, _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]); }
private static int GetCombinedSecondMaximum(SecondMaximumQueryObject leftAdjacentObject, SecondMaximumQueryObject rightAdjacentObject) => Math.Max( Math.Min(leftAdjacentObject.Maximum, rightAdjacentObject.Maximum), Math.Max(leftAdjacentObject.SecondMaximum ?? 0, rightAdjacentObject.SecondMaximum ?? 0));
public void Update(SecondMaximumQueryObject updatedLeftChild, SecondMaximumQueryObject updatedRightChild) { Maximum = GetCombinedMaximum(updatedLeftChild, updatedRightChild); SecondMaximum = GetCombinedSecondMaximum(updatedLeftChild, updatedRightChild); }