1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| class Solution { public int countRangeSum(int[] nums, int lower, int upper) { int n = nums.length; long[] preSum = new long[n + 1]; for(int i = 1; i < n + 1; i++){ preSum[i] = preSum[i - 1] + nums[i - 1]; } long[] sort = Arrays.stream(preSum).sorted().toArray(); int rank = 0; TreeMap<Long, Integer> map = new TreeMap<>(); for (int i = 0; i < n + 1; i++) { if (!map.containsKey(sort[i])) { map.put(sort[i], rank++); } } SegTree segTree = new SegTree(rank); int ans = 0; for (int i = 0; i < n + 1; i++) { Map.Entry<Long, Integer> ceil = map.ceilingEntry(preSum[i] - upper); Map.Entry<Long, Integer> floor = map.floorEntry(preSum[i] - lower); if (ceil != null && floor != null) { ans += segTree.query(ceil.getValue(), floor.getValue(), 0, rank - 1, 1); } int cur = map.get(preSum[i]); segTree.update(cur, 1, 0, rank - 1, 1); } return ans; } }
class SegTree { int[] arr;
public SegTree(int n) { this.arr = new int[n * 4]; }
public void update(int index, int c, int s, int t, int p){ if (s == t) { arr[p] += c; return; } int mid = s + (t - s >> 1); if (index <= mid) { update(index, c, s, mid, p * 2); } else { update(index, c, mid + 1, t, p * 2 + 1); } arr[p] = arr[p * 2] + arr[p * 2 + 1]; }
public int query(int l, int r, int s, int t, int p){ if (l <= s && r >= t) { return arr[p]; } int mid = s + (t - s >> 1); int sum = 0; if (l <= mid) { sum += query(l, r, s, mid, p * 2); } if (r >= mid + 1) { sum += query(l, r, mid + 1, t, p * 2 + 1); } return sum; }
}
|