您的位置:首页 > 其它

树状数组的一些认识

2010-08-05 23:32 190 查看
  int lowbit(int x){  return x&(x^(x–1));

  }

这个函数的值为2的k次方。形象的就是把二进制的最后一个1和后面的0都拿出来。

有了形象的感知,函数也就很好理解了。要是把最后一个1和零拿出来,我们先x-1,原先a100...0就变成了a011...1.a异或a为0,所以二进制就变为了000111...1。

构造线段树的规则的理解,可以从二进制中1的个数来理解。百度百科中,求和和修改的解释是不错的。

当想要查询一个SUM(n)(求a
的和),
可以依据如下算法即可:

  step1: 令sum = 0,转第二步;

  step2: 假如n <= 0,算法结束,返回sum值,否则sum = sum + Cn,转第三步;

  step3: 令n = n – lowbit(n),转第二步。

  可以看出,这个算法就是将这一个个区间的和全部加起来,为什么是效率是log(n)的呢?以下给出证明:

  n = n – lowbit(n)这一步实际上等价于将n的二进制的最后一个1减去。而n的二进制里最多有log(n)个1,所以查询效率是log(n)的。

  那么修改呢,修改一个节点,必须修改其所有祖先,最坏情况下为修改第一个元素,最多有log(n)的祖先。

  所以修改算法如下(给某个结点i加上x):

  step1: 当i > n时,算法结束,否则转第二步;

  step2: Ci = Ci + x, i = i + lowbit(i)转第一步。

  i = i +lowbit(i)

这个过程实际上也只是一个把末尾1补为0的过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: