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); }
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); }