N个花园连续编号为1到N,每个花园都有Ci胡萝卜。 我们必须将总胡萝卜的值存储在数组中每个可能的连续子序列的花园中。
现在我们必须对获得的数组进行排序并回答以下Q查询。在每个查询中,我们想要知道上面获得的排序数组中从L到R(包括两个端点)的值的总和。
示例测试用例
Input:
3 3 //First number is the total no. of gardens. Second is no. of queries
4 9 1 //No. of carrots in each of the gardens
1 6 // Query return sum from L to R.
2 4
3 3
Output:
51 23 9 // Respective Output for 3 queries.
解释
Gardens [1, 2, 3] has [4, 9, 1] carrots respectively.
All possible continuous gardens are { [1], [2], [3], [1, 2], [2, 3], [1, 2, 3] } .
Sum of carrots in each subgardens is {4, 9, 1, 13, 10, 14}
Sorted array is {1, 4, 9, 10, 13, 14} .
Now Queries for 1 6 sum is 1+4+9+10+13+14 which is 51,
next 2 4 so 4+9+10 hence 23, and 3 3 which is 9.
现在我使用模拟/后缀和解决了这个问题,但原始问题有很大的约束
1 ≤ No. of gardens ≤ 2*10^5
1 ≤ Carrots in a particular garden ≤ 100
1 ≤ Li ≤ Ri ≤ N(N+1)/2
1 ≤ No. of queries ≤ 20
现在当我尝试为N * 2 * 10 ^ 5创建所有可能的连续子序列时。总数没有。我得到的连续子序列大约是10 ^ 10,这太大而不能存储在数组中。
对此有什么可行的解决方法,如何在不实际存储所有连续子序列的总和的情况下回答查询?
答案 0 :(得分:2)
这个怎么样?
假定c[] = {c_1,c_2,..,c_n}
,给定数组。和p[] = {c1, c1+c2,..,c1+...+cn}
前缀数组。将c
的所有连续子视觉划分为n
个组(每个组都是非递减数组):
{ c1, c1+c2, .. , }
{ c2, c2+c3, .. , c2+...+cn}
...
{ cn }
请注意,使用前缀数组可以在固定时间内计算所有上述元素。
让我们找到值x
,这样我们选择的组中的l
元素就会小于x
。 (x
的最大值为c0+c1+..+cn
)。为此,我们在x
上运行二进制搜索,并为给定l
计算x
的值,我们在每个选定的组中运行二进制搜索。因此,我们将在每个组中包含少于x
的元素数,这是我们需要总结的。此操作的复杂性为n*log(x)*log(x)
。
现在我们获得范围[l, r]
。假设有l-1
个元素小于xl
和r
元素小于xr
。所以剩下的就是计算每个组中的元素总和小于xr
,并减去每个组中相应的总和小于xl
。使用二进制搜索和前缀和数组进行计算是直截了当的。
修改强>
以下是使用上述方法的解决方案:https://ideone.com/2JTw0X
请问是否有任何问题。至于如何处理的情况,如果确定范围的值不存在,我们需要计算偏移量,这非常简单。例如,在1, 1, 1, 1, 1
的情况下。建构群体是:
{1,2,3,4,5}, {1,2,3,4},...,{1}
。因此,如果我们想要找到值x
,s.t。正好三个数字小于x
,我们找到最小值x'
,s.t。 f(x') >= 3
。在这种情况下x'=1
。 f(1)=5
并且它严格大于3
,因此我们将3
(偏移)添加到答案中,并计算每个组中所有元素总和的总和,小于{{ 1}},这是零。