Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 有可能在O(n)建造一棵芬威克树吗?_Algorithm_Fenwick Tree - Fatal编程技术网

Algorithm 有可能在O(n)建造一棵芬威克树吗?

Algorithm 有可能在O(n)建造一棵芬威克树吗?,algorithm,fenwick-tree,Algorithm,Fenwick Tree,是一种允许两种操作的数据结构(您可以使用更多操作来扩充它): 点更新更新(索引、值) 前缀和查询(索引) 这两个操作都在O(log(n))中,其中n是数组的大小。我在理解如何做这两个操作以及它们背后的逻辑方面没有问题 我的问题是如何从数组初始化Fenwick树。显然,我可以在O(nlog(n))中通过调用ntimesupdate(I,arr[I])来实现这一点,但是有没有办法在O(n)中初始化它 如果维基百科告诉你可以在nlog(n)中初始化,我为什么要问这个问题?因为这篇文章非常简陋,

是一种允许两种操作的数据结构(您可以使用更多操作来扩充它):

  • 点更新
    更新(索引、值)
  • 前缀和
    查询(索引)
这两个操作都在
O(log(n))
中,其中
n
是数组的大小。我在理解如何做这两个操作以及它们背后的逻辑方面没有问题


我的问题是如何从数组初始化Fenwick树。显然,我可以在
O(nlog(n))
中通过调用
n
times
update(I,arr[I])
来实现这一点,但是有没有办法在
O(n)
中初始化它



如果维基百科告诉你可以在
nlog(n)
中初始化,我为什么要问这个问题?因为这篇文章非常简陋,所以我不确定它是否是一个人所能达到的最佳复杂性。与原始堆创建(通过一个接一个地填充堆来完成)相比较,原始堆创建可以在
O(nlog(n))
中实现,而
O(n)
中的智能堆初始化让我希望在Fenwick树中也可以做类似的事情。

[编辑:我的事情“颠倒了”——现在已经修复!]

对。以递增索引顺序循环n个数组项,始终仅将总和添加到下一个最小的应添加到的索引中,而不是添加到所有索引中:

for i = 1 to n:
    j = i + (i & -i)     # Finds next higher index that this value should contribute to
    if j <= n:
        x[j] += x[i]
对于i=1到n:
j=i+(i&-i)#查找该值应贡献的下一个更高的索引

如果j以下是Java实现:

public BIT(long[] nums) {
        bit = new long[nums.length + 1]; //one-indexed
        for (int i = 1; i <= nums.length; i++) {
            bit[i] += nums[i - 1]; //update node
            if (i + (i & -i) <= nums.length) {
                bit[i + (i & -i)] += bit[i]; //update parent
            }
        }
    }
公共位(长[]nums){
位=新长[nums.length+1];//一个索引

对于(int i=1;我印象深刻!虽然这会破坏起始数组,但始终可以将其复制到其他位置并处理副本。非常有趣的方法!跨站点复制:@DavidEisenstat No duplicate,因为检查了
O(n*log(n))
,这里是
O(n)
请求并提供了算法。尽管发现得很好。@Vesper这是一个O(n logn)-时间算法,经过更仔细的分析,它是O(n)。链接到的问题@Davidisenstat的更新显示,所讨论的算法毕竟不是幼稚的算法(从经验上看,它似乎是ω(n logn)),但它实际上与我的非常相似——唯一的区别是它“拉”值,而不是“推”值。