在比线性时间更快的时间内找到满足 属性 的范围
Finding a range satisfying a property in faster than linear time
给定一个数组 A[],我们需要找到一个具有最大大小且其最小元素 >= 1 的范围。我们还需要通过将其所有元素减 1 来更新此范围。
我想到的一个想法是保留一个线段树以进行高效更新。但是如何在 <= 对数时间内获得范围?
也许我们可以在这里使用二进制搜索。
谢谢
这个问题很有意思,我觉得可以用线段树来解决。
这是我的想法(我希望它能足够快地工作):
对于每个段,我们需要存储 4 个信息:
- 数字的最左边索引 < 1
- 数字 < 1 的最右边索引
- 此段的最大大小(存储为范围 a 和 b)
- 惰性标志 (true/false)
当我们想要查询最大尺寸时,我们可以通过递归调用来计算最终答案。
假设我们的方法是 calcAnswer(left,right).
resA = calcAnswer(左,中);
resB = calcAnswer(mid+1,right);
最大尺寸将为 max(resA.max_size, resB.max_size, combine(resA.right_index,resB.left_index)).
如果数组A[]的元素个数较少(N<=50000),我们可以使用Mo's Algorithm.
给定一个数组 A[],我们需要找到一个具有最大大小且其最小元素 >= 1 的范围。我们还需要通过将其所有元素减 1 来更新此范围。
我想到的一个想法是保留一个线段树以进行高效更新。但是如何在 <= 对数时间内获得范围?
也许我们可以在这里使用二进制搜索。
谢谢
这个问题很有意思,我觉得可以用线段树来解决。
这是我的想法(我希望它能足够快地工作):
对于每个段,我们需要存储 4 个信息:
- 数字的最左边索引 < 1
- 数字 < 1 的最右边索引
- 此段的最大大小(存储为范围 a 和 b)
- 惰性标志 (true/false)
当我们想要查询最大尺寸时,我们可以通过递归调用来计算最终答案。 假设我们的方法是 calcAnswer(left,right).
resA = calcAnswer(左,中);
resB = calcAnswer(mid+1,right);
最大尺寸将为 max(resA.max_size, resB.max_size, combine(resA.right_index,resB.left_index)).
如果数组A[]的元素个数较少(N<=50000),我们可以使用Mo's Algorithm.