定义

    二叉索引树,binary index tree,又名树状数组,或Fenwick Tree,因为本算法由Fenwick创造。

    对于数组A,定义Query(i,j) = Ai +Ai+1 + … + Aj.

    比较好的做法:使用前缀和,Sum(j) – Sum(i-1)即可得到Query(i,j)

    BIT即为解决此类区间查询而大展身手,因为预处理时间为O(n),之后的查询时间为O(1),是属于典型的在线算法(关于在线算法,通俗地可以理解为,做一次预处理,提供多次“服务”——比如多次Query(i,j))。

Lowbit(nature)

    首先,定位lowbit(natural)为自然数(即1,2,3…n)的二进制形式中最右边出现1的值。

    比如:4 = 100,lowbit(4) = 4;36 = 100100,lowbit(36) = 4.

    自然数在二进制形式下,有如下的性质:

    Lowbit为1的自然数为1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31…d = 2

    Lowbit为2的自然数为2,6,10,14,18,22,26,30,… d = 4

    Lowbit为3的自然数为4,12,20,28… d=8

    Lowbit为4的自然数为8,32

    直接上刘汝佳的算法竞赛入门竞赛经典中的图片:

    

    树状性质:对于节点i,如果他是左子结点,那么父节点的编号就是i+lowbit(i);如果它是右子节点,那么父节点的编号是i-lowbit(i)。

    令数组C为:

     Ci = Ai-lowbit(i)+1+A i-lowbit(i)+2+…Ai

    即从最左边的孩子,到自身的和,如C12 = A9(上图中最左边的儿子)+A10+A11+A12,C6=A5+A6。

    计算前缀和Sum(i)的计算:

    顺着节点i往左走,边走边“往上爬”,把经过的Ci 累加起来即可。

API

    l lowbit(idx)

      求A[idx]的低位

    l Sum(i)

     求区间1,i的前缀和

    l Add(idx,value)

      使节点idx的值增加value;

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Algorithms.Data_Structure
{
/// <summary>
/// 二叉索引树(树状数组:Fenwick Tree)
/// </summary>
public class BinaryIndexedTree
{
/// <summary>
/// 处理的数组
/// </summary>
private List<int> array; /// <summary>
/// 二叉前缀和
/// </summary>
private List<int> tree; /// <summary>
/// 个数
/// </summary>
private int n; public BinaryIndexedTree(int[] array)
{
this.array = new List<int>(array);
this.n = this.array.Count; PreProcessing();
} /// <summary>
/// 预处理函数:每次增加数值
/// </summary>
private void PreProcessing()
{
tree = new List<int>(n);
for (int ii = 0; ii < n; ii++)
{
tree.Add(0);
} for (int ii = 1; ii < n; ii++)
{
Update(ii, array[ii]);
}
} /// <summary>
/// 二进制形式中的最右边的1所对应的值,如38288 = 1001010110010000 ,则返回16
/// </summary>
/// <param name="idx"></param>
private int lowbit(int idx)
{
return idx & (-idx);
} /// <summary>
/// 在x处加v
/// </summary>
/// <param name="idx">数组的索引,从1开始计数</param>
/// <param name="v">值</param>
public void Update(int idx, int v)
{
while (idx < n)
{
tree[idx] += v;
idx += lowbit(idx); //left's parent
}
} /// <summary>
/// 从0到x求和
/// </summary>
/// <param name="idx">索引,从1开始计数</param>
/// <returns>求和结果</returns>
public int Sum(int idx)
{
int ret = 0;
while (idx > 0)
{
ret += tree[idx];
idx -= lowbit(idx); // right's parent
}
return ret;
}
}
}

Test:

class Program
{
static void Main(string[] args)
{
BinaryIndexedTree bit = new BinaryIndexedTree(new int[] { 0, 1, 2, 3, 4, 5 }); //从1开始计数
Console.WriteLine(bit.Sum(5));//15
bit.Update(4, 23);
Console.WriteLine(bit.Sum(5));//38
}
}

二叉索引树BIT的更多相关文章

  1. 【转载】区间信息的维护与查询(一)——二叉索引树(Fenwick树、树状数组)

    在网上找到一篇非常不错的树状数组的博客,拿来转载,原文地址. 树状数组 最新看了一下区间的查询与修改的知识,最主要看到的是树状数组(BIT),以前感觉好高大上的东西,其实也不过就这么简单而已. 我们有 ...

  2. C++实用数据结构:二叉索引树

    看下面这个问题(动态连续和查询): 有一个数组A(长度为n),要求进行两种操作: add(i,x):让Ai增大x: query(a,b):询问Aa+Aa+1+...+Ab的和: 若进行模拟,则每次qu ...

  3. POJ 3321 Apple Tree dfs+二叉索引树

    题目:http://poj.org/problem?id=3321 动态更新某个元素,并且求和,显然是二叉索引树,但是节点的标号不连续,二叉索引树必须是连续的,所以需要转化成连续的,多叉树的形状已经建 ...

  4. NYOJ 116 士兵杀敌(二)(二叉索引树)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=116 题意: 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的 ...

  5. HDU 1166 敌兵布阵(线段树 or 二叉索引树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N<=50000),表示敌人有 ...

  6. 【树状数组(二叉索引树)】轻院热身—candy、NYOJ-116士兵杀敌(二)

    [概念] 转载连接:树状数组 讲的挺好. 这两题非常的相似,查询区间的累加和.更新结点.Add(x,d) 与 Query(L,R) 的操作 [题目链接:candy] 唉,也是现在才发现这题用了这个知识 ...

  7. 树状数组(二叉索引树 BIT Fenwick树) *【一维基础模板】(查询区间和+修改更新)

    刘汝佳:<训练指南>Page(194) #include <stdio.h> #include <string.h> #include <stdlib.h&g ...

  8. 二叉索引树,LA2191,LA5902,LA4329

    利用了二进制,二分的思想的一个很巧妙的数据结构,一个lowbit(x):二进制表示下的最右边的一个1开始对应的数值. 那么如果一个节点的为x左孩子,父亲节点就是 x + lowbit(x),如果是右孩 ...

  9. 1.红黑树和自平衡二叉(查找)树区别 2.红黑树与B树的区别

    1.红黑树和自平衡二叉(查找)树区别 1.红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单. 2.平衡 ...

随机推荐

  1. cocos基础教程(12)点击交互的三种处理

    1.概述 游戏也好,程序也好,只有能与用户交互才有意义.手机上的交互大致可以分为两部分:点击和输入.其中点击更为重要,几乎是游戏中全部的交互.在Cocos2d-x 3.0中,更改了dispatch机制 ...

  2. Java之内存分析和String对象

    原文地址:http://www.cnblogs.com/devinzhang/archive/2012/01/25/2329463.html 文中 s2后面的注释是错误的,应该是”创建一个对象(堆中) ...

  3. Ubuntu下为Firefox安装Adobe Flash Player

      使用环境:     OS:Ubuntu 12.04 LTS     Browser: Firefox 12.0     Adobe Flash Player: install_flash_play ...

  4. poj1182(食物链)续

    意 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用 ...

  5. Linux zabbix 配置注意事项

    发现php-fpm启动之后,找不到 php-fpm.pid文件??? vi php-fpm.conf 去掉里面那个 pid = run/php-fpm.pid 前面的分号然后再启动php-fpm才能自 ...

  6. 九度 OJ1008 hdu 3790

    #include<stdio.h> #include<string.h> struct node { int d; int p; }g[][]; #define inf 0x3 ...

  7. BZOJ 3540 realtime-update 解题

    分析一下题意,大约是给定一串牛,然后找到一个跨越距离最长的牛子串使得在这个范围内白牛和花牛一样多. 白牛可以任意涂成花牛. 既然"白牛可以任意涂成花牛",那么我们需要找到一个最长的 ...

  8. scrapy和selenium结合抓取动态网页

    1.安装python (我用的是2.7版本的) 2.安装scrapy:   详情请参考 http://blog.csdn.net/wukaibo1986/article/details/8167590 ...

  9. 61. 从1到n,共有n个数字,每个数字只出现一次。从中随机拿走一个数字x,请给出最快的方法,找到这个数字。如果随机拿走k(k>=2)个数字呢?[find k missing numbers from 1 to n]

    [本文链接] http://www.cnblogs.com/hellogiser/p/find-k-missing-numbers-from-1-to-n.html  [题目] 从1到n,共有n个数字 ...

  10. iOS7 和 iOS6的页面兼容问题

    ios7 的status bar变透明了,各个bar也透明了,一个controller的view占据了整个屏幕.怎么调整呢?基本的思想是把内容的坐标下移.如果仅仅把内容的y坐标下移,那么在ios6上显 ...