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);
            }
Beispiel #5
0
            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));
     }
 }
Beispiel #7
0
            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);
            }
Beispiel #8
0
 public SegmentTreeNode(int s, int e, int val)
 {
     start = s;
     end   = e;
     sum   = val;
     left  = null;
     right = null;
 }
Beispiel #9
0
            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);
            }
Beispiel #10
0
 public SegmentTreeNode(int minValue, int maxValue)
 {
     this._minValue   = minValue;
     this._maxValue   = maxValue;
     this._leftChild  = null;
     this._rightChild = null;
     this._allExist   = false;
 }
Beispiel #11
0
 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);
 }
Beispiel #12
0
            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);
            }
Beispiel #13
0
 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));
 }
Beispiel #14
0
            public SegmentTree(int[] nums)
            {
                if (!nums.Any())
                {
                    return;
                }

                m_rootNode = new SegmentTreeNode(0, nums.Length - 1);

                Recursion(m_rootNode);

                GetNodeRangeSum(m_rootNode, nums);
            }
Beispiel #15
0
            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));
            }
Beispiel #16
0
        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();
        }
Beispiel #17
0
            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);
            }
Beispiel #18
0
            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));
            }
Beispiel #19
0
            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)));
            }
Beispiel #21
0
    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);
    }
Beispiel #22
0
            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));
            }
Beispiel #24
0
            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);
            }
Beispiel #25
0
    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);
    }
Beispiel #26
0
    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));
        }
    }
Beispiel #27
0
            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);
            }
Beispiel #28
0
                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);
 }