找到 min(max(A[L], A[L+1],...,A[R]), min(B[L], B[L+1],..., B[R]) 的有效方法))

时间:2021-07-12 14:34:02

标签: algorithm max min

给定 2 个数组 A[N] 和 B[N]。对于每个 0 <= L < N <= 5e5,求

的最大值
min(max(A[L], A[L+1],...,A[R]), min(B[L], B[L+1],…, B[R])) 

对于 L <= R <= N。

ans[L] 是 L 的答案。
例如,
N = 3
A[3] = {3, 2, 1}
B[3] = {3, 2, 3}
所以,答案是
答案[0] = 3
答案[1] = 2
答案[2] = 1

很明显,蛮力可以运行得很快。
然后,我尝试使用 Sparse table、Segment Tree 或 Binary Indexed Tree(我们不需要更新任何东西,所以我选择了 Sparse Table)。但是对于每个 L,我们不知道 R,所以我需要运行到数组的末尾,这与 brute-forces 没有什么不同。

对于这个问题,有什么有效的算法或数据结构吗??

P/s:抱歉我的英语不好。

2 个答案:

答案 0 :(得分:2)

使用稀疏表 A 是单调递增,B 是单调递减,因此我们需要找到交叉点以从它们的最小值中获取最大值......

伪python代码未经测试

stA = SparseTable(A);
stB = SparseTable(B);

for (i in range(len(A))
  r = len(B)
  l = i

  a = stA.max(l,r)
  b = stB.min(l,r)

  # binary search for crossing point
  while (l != r)
    m = l + (r-l)//2  # integer division 
    a = stA.max(l,m)
    b = stB.min(l,m)
    if (b > a)
      l = m + 1
    else
      r = m

  ans[i] = min(a,b) # might be off-by-one m?

答案 1 :(得分:1)

max(A[L], A[L+1], ..., A[R]) 在 L 中不增加,在 R 中不减少。相反,min(B[L], B[ L+1], ..., B[R]) 在 L 中不减少,在 R 中不增加。由此可知,从 L 到 R 中的 argmax 的函数是不减少的。最后一个成分是两个队列,一个可以报告最大值,一个可以报告最小值,以快速计算滑动窗口聚合。