↓ 跳过正文
  1. 科学/
  2. 计算机/
  3. 算法/
  4. Leetcode/
  5. 0300-0399/

0327 区间和的个数

Solution

from typing import List
from itertools import accumulate
import bisect

class BinaryIndexedTree:
    def __init__(self, n):
        self.n = n
        self.c = [0] * (n + 1)

    def update(self, x, v):
        while x <= self.n:
            self.c[x] += v
            x += x & -x

    def query(self, x):
        s = 0
        while x > 0:
            s += self.c[x]
            x -= x & -x
        return s


class Solution:
    def countRangeSum(self, nums: List[int], lower: int, upper: int) -> int:
        s = list(accumulate(nums, initial=0))
        arr = sorted(set(v for x in s for v in (x, x - lower, x - upper)))
        tree = BinaryIndexedTree(len(arr))
        ans = 0
        for x in s:
            l = bisect_left(arr, x - upper) + 1
            r = bisect_left(arr, x - lower) + 1
            ans += tree.query(r) - tree.query(l - 1)
            tree.update(bisect_left(arr, x) + 1, 1)
        return ans

if __name__ == "__main__":
    sol = Solution()
    print(sol.countRangeSum([-2,5,-1], -2, 2)) # 3
    print(sol.countRangeSum([0,0], 0,0))       # 3