public int CountRangeSumSegTree(int[] nums, int lower, int upper)
        {
            // prefix sum; use long to avoid overflow
            var sums = new long[nums.Length + 1];

            for (int i = 0; i < nums.Length; i++)
            {
                sums[i + 1] = sums[i] + nums[i];
            }

            // intially the Count of all prefix sum is 0; use set to remove duplicates
            var tree = new SegmentCountTree(new SortedSet <long>(sums).ToArray());

            int ret = 0;

            for (int i = 0; i < nums.Length; i++)
            {
                // set the Count of previous prefix sum
                tree.Update(sums[i]);

                // query the count of j, where lower <= sum[i] - sum[j] <= upper, that is sum[i] - upper <= sum[j] <= sum[i] - lower
                ret += tree.Query(sums[i + 1] - upper, sums[i + 1] - lower);
            }

            return(ret);
        }
Beispiel #2
0
        public IList <int> CountSmallerSegtree(int[] nums)
        {
            var tree = new SegmentCountTree(new SortedSet <int>(nums).ToArray());
            var ret  = new int[nums.Length];

            for (int i = nums.Length - 1; i >= 0; i--)
            {
                ret[i] = tree.Query(nums[i]);
                tree.Update(nums[i]);
            }
            return(ret);
        }