给定 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:抱歉我的英语不好。
答案 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 的函数是不减少的。最后一个成分是两个队列,一个可以报告最大值,一个可以报告最小值,以快速计算滑动窗口聚合。