private void ChangeCount(SegmentTreeNode node, int value, int delta, int left, int right) { node.Count += delta; if (left == right) { return; } int mid = (left + right) / 2; if (value <= mid) { if (node.Left == null) { node.Left = new SegmentTreeNode(); } this.ChangeCount(node.Left, value, delta, left, mid); } else { if (node.Right == null) { node.Right = new SegmentTreeNode(); } this.ChangeCount(node.Right, value, delta, mid + 1, right); } }
public void AddRange(int left, int right) { if (left <= this._minValue && this._maxValue <= right) { this._allExist = true; this._leftChild = null; this._rightChild = null; return; } int middle = (this._minValue + this._maxValue) / 2; if (left < middle) { // Add [left, middle) into left subtree if (this._leftChild == null) { this._leftChild = new SegmentTreeNode(this._minValue, middle); } this._leftChild.AddRange(left, middle); } if (right > middle) { // Add [middle, right) into right subtree if (this._rightChild == null) { this._rightChild = new SegmentTreeNode(middle, this._maxValue); } this._rightChild.AddRange(middle, right); } }
private void RecursiveInit(SegmentTreeNode root, int min, int max) { if (min > max) { return; } root.m_NumRange = new int[] { min, max }; if (min == max) { return; } var middleTemp = min + (max - min) / 2; if (min <= middleTemp) { root.m_LeftRange = new SegmentTreeNode(); RecursiveInit(root.m_LeftRange, min, middleTemp); } if (middleTemp + 1 <= max) { root.m_RightRange = new SegmentTreeNode(); RecursiveInit(root.m_RightRange, middleTemp + 1, max); } }
private SegmentTreeNode Add(SegmentTreeNode rootNode, ulong left, ulong right, ulong value) { if (left > right) { return(null); } SegmentTreeNode node = rootNode != null ? rootNode : new SegmentTreeNode(); if (left == right) { node.Value = value; } else { ulong m = (left + right) / 2; if (value <= m) { node.Left = this.Add(node.Left, left, m, value); } else { node.Right = this.Add(node.Right, m + 1, right, value); } this.UpdateNode(node); } return(node); }
static private SegmentTreeNode AddInternal(SegmentTreeNode node, int left, int right, long pos) { if (left > right) { return(null); } node = node == null ? new SegmentTreeNode() : node; if (left == right) { node.Value++; return(node); } int mid = (left + right) / 2; if (pos <= mid) { node.Left = AddInternal(node.Left, left, mid, pos); } else { node.Right = AddInternal(node.Right, mid + 1, right, pos); } node.Value = GetValue(node.Left) + GetValue(node.Right); return(node); }
private void UpdateNode(SegmentTreeNode node) { if (node != null) { node.Value = Math.Min(this.GetNodeValue(node.Left), this.GetNodeValue(node.Right)); } }
private SegmentTreeNode Add(int left, int right, int treeLeft, int treeRight, SegmentTreeNode node) { if (left > right || treeLeft > treeRight || left > treeRight || right < treeLeft) { return(node); } if (node == null) { node = new SegmentTreeNode(); } if (treeLeft >= left && treeRight <= right) { node.Sum++; } else { int m = (treeLeft + treeRight) / 2; node.Left = this.Add(left, right, treeLeft, m, node.Left); node.Right = this.Add(left, right, m + 1, treeRight, node.Right); } return(node); }
public SegmentTreeNode(int s, int e, int val) { start = s; end = e; sum = val; left = null; right = null; }
private int GetNodeRangeSum(SegmentTreeNode root, int[] nums) { root.SumValue = root.MinIndex == root.MaxIndex ? nums[root.MinIndex] : GetNodeRangeSum(root.LeftNode, nums) + GetNodeRangeSum(root.RightNode, nums); return(root.SumValue); }
public SegmentTreeNode(int minValue, int maxValue) { this._minValue = minValue; this._maxValue = maxValue; this._leftChild = null; this._rightChild = null; this._allExist = false; }
void Update(SegmentTreeNode node, int value) { if (node == null || value < node.Min || node.Max < value) { return; } node.Count++; Update(node.Left, value); Update(node.Right, value); }
private void UpdateTreeRecursion(SegmentTreeNode root, int i, int addValue) { if (root == null || i < root.MinIndex || i > root.MaxIndex) { return; } root.SumValue += addValue; UpdateTreeRecursion(root.LeftNode, i, addValue); UpdateTreeRecursion(root.RightNode, i, addValue); }
int Query(SegmentTreeNode node, int value) { if (node == null || value <= node.Min) { return(0); } if (node.Max < value) { return(node.Count); } return(Query(node.Left, value) + Query(node.Right, value)); }
public SegmentTree(int[] nums) { if (!nums.Any()) { return; } m_rootNode = new SegmentTreeNode(0, nums.Length - 1); Recursion(m_rootNode); GetNodeRangeSum(m_rootNode, nums); }
private int SumTreeRecursion(SegmentTreeNode root, int i, int j) { if (root == null || root.MinIndex > j || root.MaxIndex < i) { return(0); } if (root.MinIndex >= i && root.MaxIndex <= j) { return(root.SumValue); } return(SumTreeRecursion(root.LeftNode, i, j) + SumTreeRecursion(root.RightNode, i, j)); }
public void Test() { var root = new SegmentTreeNode<int>(StringComparer.InvariantCultureIgnoreCase); root.Search(new[] {"a"}, 0).Should().BeEmpty(); root.Add(new[] {"a", "b", "c"}, 0, 42).Should().BeTrue(); root.Search(new[] {"a"}, 0).Should().BeEquivalentTo((new[] {"a", "b", "c"}, 42)); root.Search(new[] {"a", "b"}, 0).Should().BeEquivalentTo((new[] {"a", "b", "c"}, 42)); root.Search(new[] {"a", "b", "c"}, 0).Should().BeEquivalentTo((new[] {"a", "b", "c"}, 42)); root.Search(new[] {"a", "b", "c", "d"}, 0).Should().BeEmpty(); root.Add(new[] {"a", "b"}, 0, 42).Should().BeFalse(); root.Delete(new[] {"a", "b", "c"}, 0).Should().BeTrue(); root.Search(new[] {"a"}, 0).Should().BeEmpty(); }
private void Recursion(SegmentTreeNode root) { if (root.MinIndex == root.MaxIndex) { return; } var middle = root.MinIndex + (root.MaxIndex - root.MinIndex) / 2; root.LeftNode = new SegmentTreeNode(root.MinIndex, middle); root.RightNode = new SegmentTreeNode(middle + 1, root.MaxIndex); Recursion(root.LeftNode); Recursion(root.RightNode); }
static private long GetInternal(SegmentTreeNode node, int left, int right, long queryLeft, long queryRight) { if (queryLeft > right || queryRight < left || node == null) { return(0); } if (left >= queryLeft && right <= queryRight) { return(node.Value); } int mid = (left + right) / 2; return(GetInternal(node.Left, left, mid, queryLeft, queryRight) + GetInternal(node.Right, mid + 1, right, queryLeft, queryRight)); }
private int Get(int index, int treeLeft, int treeRight, SegmentTreeNode node) { if (treeLeft > treeRight || index > treeRight || index < treeLeft || node == null) { return(0); } int m = (treeLeft + treeRight) / 2; if (index <= m) { return(node.Sum + this.Get(index, treeLeft, m, node.Left)); } return(node.Sum + this.Get(index, m + 1, treeRight, node.Right)); }
private ulong Get(SegmentTreeNode rootNode, ulong segmentLeft, ulong segmentRight, ulong left, ulong right) { if (rootNode == null || segmentLeft > right || segmentRight < left) { return(this.Max); } if (segmentLeft >= left && segmentRight <= right) { return(rootNode.Value); } ulong m = (segmentLeft + segmentRight) / 2; return(Math.Min(this.Get(rootNode.Left, segmentLeft, m, left, right), this.Get(rootNode.Right, m + 1, segmentRight, left, right))); }
private int UpdateTree(int index, int val, SegmentTreeNode root) { int diff = 0; if (root.start == root.end && index == root.start) { diff = val - root.sum; root.sum = val; return(diff); } int mid = root.start + (root.end - root.start) / 2; diff = UpdateTree(index, val, index > mid ? root.right : root.left); root.sum += diff; return(diff); }
private void RecursiveUpdateNode(SegmentTreeNode root, int value) { if (root == null) { return; } if (value < root.m_NumRange[0] || value > root.m_NumRange[1]) { return; } root.m_CurCount++; RecursiveUpdateNode(root.m_LeftRange, value); RecursiveUpdateNode(root.m_RightRange, value); }
private int GetValue(SegmentTreeNode node, int count, int left, int right) { if (left == right) { return(left); } int mid = (left + right) / 2; int leftCount = this.GetCount(node.Left); if (leftCount >= count) { return(this.GetValue(node.Left, count, left, mid)); } return(this.GetValue(node.Right, count - leftCount, mid + 1, right)); }
SegmentTreeNode Build(int[] nums, int lo, int hi) { if (lo > hi) { return(null); } var node = new SegmentTreeNode(nums[lo], nums[hi]); if (lo == hi) { return(node); } int m = (lo + hi) / 2; node.Left = Build(nums, lo, m); node.Right = Build(nums, m + 1, hi); return(node); }
private SegmentTreeNode BuildTree(int[] nums, int s, int e) { if (e < s) { return(null); } if (s == e) { return(new SegmentTreeNode(s, e, nums[s])); } int mid = s + (e - s) / 2; var left = BuildTree(nums, s, mid); var right = BuildTree(nums, mid + 1, e); var node = new SegmentTreeNode(s, e, (left == null?0:left.sum) + (right == null?0:right.sum)); node.left = left; node.right = right; return(node); }
private int SumRange(SegmentTreeNode root, int i, int j) { if (i == root.start && j == root.end) { return(root.sum); } int mid = root.start + (root.end - root.start) / 2; if (i > mid) { return(SumRange(root.right, i, j)); } else if (j <= mid) { return(SumRange(root.left, i, j)); } else { return(SumRange(root.left, i, mid) + SumRange(root.right, mid + 1, j)); } }
private int RecursiveSearch(SegmentTreeNode root, int min, int max) { if (min > max || root == null) { return(0); } if (root.m_NumRange[1] < min || root.m_NumRange[0] > max) { return(0); } if (root.m_NumRange[1] <= max && root.m_NumRange[0] >= min) { return(root.m_CurCount); } var leftValueTemp = RecursiveSearch(root.m_LeftRange, min, max); var rightValueTemp = RecursiveSearch(root.m_RightRange, min, max); return(leftValueTemp + rightValueTemp); }
public void RemoveRange(int left, int right) { if (left <= this._minValue && this._maxValue <= right) { this._allExist = false; this._leftChild = null; this._rightChild = null; return; } int middle = (this._minValue + this._maxValue) / 2; if (left < middle) { // Remove [left, middle) into left subtree this._leftChild?.RemoveRange(left, middle); } if (right > middle) { // Remove [middle, right) into right subtree this._rightChild?.RemoveRange(left, middle); } }
public void Add(ulong value) { this.rootNode = this.Add(this.rootNode, 0, this.Max, value); }
private ulong GetNodeValue(SegmentTreeNode node) { return(node != null ? node.Value : this.Max); }