计数子阵列的总和在[L,R]范围内

问题描述 投票:1回答:2

我正在解决竞争性编程问题,它被描述为:

给定n <10 ^ 5整数a1,a2,a3,...,an和L,R。有多少个子阵列,使得其元素之和在[L,R]范围内。

例:

输入:

n = 4, L = 2, R = 4
1 2 3 4

产量:4

(4 = 4, 3 = 1 + 2 = 3, 2 = 2)

我有一个解决方案是暴力,但是O(n ^ 2)太慢了。我应该使用哪些数据结构/算法来有效地解决这个问题?

algorithm data-structures
2个回答
3
投票

计算前缀和(p [0] = 0,p [1] = a1,p [2] = a1 + a2,...,p [n] =所有数字的总和)。

对于固定前缀sum p [i],您需要找到j小于i且p [i] - R <= p [j] <= p [i]的此类前缀和p [j]的数量 - L.可以使用treap或其他平衡二叉搜索树在O(log n)中执行此操作。

伪代码:

treap.add(0)
sum = 0
ans = 0
for i from 1 to n:
    sum += a[i]
    left, right = treap.split(sum - R)
    middle, right = right.split(sum - L)
    ans += middle.size()
    merge left, middle and right together
    treap.add(sum)

2
投票

如果数组只包含正数,我们可以在线性时间内完成。

首先从左到右构建一个前缀为sum的数组。

1. Fix three pointers, X, Y and Z and initialize them with 0
2. At every step increase X by 1
3. While sum of numbers between X and Y are greater than R keep increasing Y
4. While sum of numbers between X and Z are greater than or equal to L, keep increasing Z
5. If valid Y and Z are found, add Z - Y + 1 to result.
6. If X is less than length of the array, Go to step 2.
© www.soinside.com 2019 - 2024. All rights reserved.