我有一个包含N个元素的数组,我需要找到子数组中等于元素的索引之间的距离;我们将以查询(L R)的形式得到,其中L是子阵列的起始索引,R是结束索引中的R. 阵列元素的总数可以是 N <= 10 ^ 5 和查询 Q <= 10 ^ 5 。
例如:
7
0 4 0 8 0 32 0
2
0 2
0 5
//第一个查询的答案是2(索引2-0)
//第二次查询答案为8(索引(2-0)+(4-2)+(4-0))
编辑:我不期待代码(虽然它会非常有用),解决的一般想法将是一个很大的帮助。
答案 0 :(得分:0)
这是sqrt分解的工作。
我们希望保持允许我们回答当前范围并调整当前范围的端点的状态。为此,我们维护一个从元素到(当前范围内该元素的所有索引的总和,当前范围中出现次数的总和)的映射。我们也保持目前的答案。要向下调整下端点以在索引i处包含元素x,我们通过范围中的索引之和递增答案 - (范围内的x的出现次数* i),然后增加总和和出现次数。其他三个操作是相似的。
为了实现sqrt分解,我们按以下方式对查询进行排序(下端点除以sqrt N,上端点)并按顺序调整范围。
答案 1 :(得分:0)
创建一个地图,其键是数组的元素,值是它们出现的位置列表(您的示例将变为{0: [0, 2, 4, 6], 8: [3], 4: [1], 32: [5]}
)。这些群体形成了无关的问题。找到答案的一种方法是将它们视为maximum flow problems,其中每个索引形成两个顶点。
每个索引都连接到它后面的所有索引,并且它之前的所有索引都连接到它。边缘的权重是阵列中元素的距离,即两个索引之间的差异。所有&#34;来源&#34;顶点连接到无限源和所有&#34;目的地&#34;顶点连接到接收器
所有问题的最大流量值之和是您要查找的总和。
例如,让我们使用项0
的索引:
+-------- 0 ----------+ 0 --------+
| | |
| | |
Source ----+-------- 2 -------+ +----> 2 --------+---- Sink
| | | |
| | | |
+-------- 4 ----+ +--+----> 4 --------+
| | | | |
| | | | |
+-------- 6 +--+--+----> 6 --------+
Weight of arc (u, v) = v - u
请注意,边数增长为V ^ 2,因为每个边对应于为计算结果而必须做的差异,这些差异在每个索引及其所有后继之间。这使得解决方案O(n ^ 3)的复杂性甚至比天真算法更糟糕,它只是从另一个角度查看事物的好方法:)