在查询后查找每个索引的最小值,该查询告诉您一个范围内的最小值

时间:2015-07-12 13:36:59

标签: c++ c algorithm

假设最初在数组a中每个元素都有无穷大作为值。

现在M类型的l r x l类型的查询已输入。

此处ra[i]>xl<=i<=r l<=r<=nM所需的值更新范围。

memset(a,inf,sizeof(a)); while(j<m) { scanf("%d %d %d",&l,&r,&c); for(i=l-1;i<r;i++) { if(a[i]>c) a[i]=c; } j++; } for(i=0;i<n;i++) printf("%d",a[i]); 次查询后,您需要输出每个索引的最小值。

一种方法是使用暴力

var response: AnyObject = prefs.objectForKey("response")!
response = response.stringByReplacingOccurrencesOfString("-", withString: "\n")
msglbl.numberOfLines = 0;
msglbl.text = "\(response)"  

msglbl.textAlignment = .Center;
msglbl.sizeToFit()
self.view.addSubview(msglbl)
msglbl.font = UIFont(name: "Gotham-Book", size: 16)

现在这需要O(mn)时间,其中n =每个查询的大小,在最坏的情况下可以是n。

在较短的时间复杂度下,有哪些更有效的方法可以解决这个问题?

2 个答案:

答案 0 :(得分:1)

注意:我的回答是假设问题在线,因此您必须在到达时执行更新和查询。这样做的一个优点是我的解决方案更加强大,允许您以相同的复杂性添加更多类型的更新和查询。缺点是,如果您正在处理离线问题,它可能不是您问题的绝对最佳选择。

您可以使用segment tree。让段树中的每个节点存储为其关联间隔设置的最小值(最初为无穷大,非常大)并使用延迟更新和查询方案。

更新(左,右,c)

Update(node, left, right, c):
  if node.interval does not intersect [left, right]:
    return
  if node.interval included in [left, right]:
    node.minimum = min(c, node.minimum)
    return

  Update(node.left, left, right, c)
  Update(node.right, left, right, c)

<强>查询(指数)

Query(node, minimum = infinity, index):
  if node.interval == [index, index]:
    return minimum

  if index included in node.left.interval:
    return Query(node.left, min(minimum, node.minimum), index)

  return Query(node.right, min(minimum, node.minimum), index)

每次更新和查询操作的总复杂度:O(log n)。您需要为最后的每个元素调用Query

答案 1 :(得分:1)

有一种方法具有不同的渐近复杂度。它涉及保留查询开始和结束的排序列表。为了避免实际排序,我使用了大小为a的稀疏数组。

现在,一般的想法是你存储查询,在迭代时你保持一个包含查询的堆是你的范围:

# size of array (n)
count = ...
# for each array element you have a list of ranges that
# start or end at this array element
list<queries> l[count]
list<queries> r[count]
heap<queries> h
for i in range(count):
    if l[i]:
        h.push(l[i])
    if h is empty:
        output(inf)
    else:
        output(h.lowest().value)
    if r[i]:
        h.pop(r[i])

这个(以及其他算法)的实际性能在很大程度上取决于数组的大小和查询的密度,但这些算法的渐近复杂性都没有涵盖。在忽略实际输入数据的同时,无法找到最佳算法。根据数据改变算法也是值得的。