我正在解决竞争性编程问题,它的描述如下:
给定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)太慢了。我应该使用哪些数据结构/算法来有效地解决这个问题?
答案 0 :(得分:3)
计算前缀和(p [0] = 0,p [1] = a1,p [2] = a1 + a2,...,p [n] =所有数字的总和)。
对于固定前缀sum p [i],您需要找到j小于i且p [i] -R <= p [j] <=的这种前缀和p [j]的数量p [i] - 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)
答案 1 :(得分: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.