Fenwick Tree
来源:互联网 发布:pk10助赢软件cpzyrj 编辑:程序博客网 时间:2024/05/29 05:57
Fenwick树,俗称树状数组
也就是二叉索引树(Binary Indexed Tree,BIT)
它的作用是什么呢
支持快速区间信息的维护和查询
为什么说是快速,因为它真的很快
O(nlog n)预处理
O(log n)维护和更新
先来看一个问题
给定一个n个元素的数组A
我们进行下面两个操作
1 add(x,d): 让A[x]增加d
2 query(l,r): 计算A[l]+A[l+1]+…+A[r]
怎么办
计算前缀和S,这可以在O(1)的时间解决query。但一旦进行add之后前缀后要重新算过。
不难发现如果进行add(x,d),对前面的前缀和是没有影响的,所以只要更新x之后的就好了
但其实还是不行,以为每次更新的花费还是很大
为什么花费会大
因为一个S的信息存储太大了,所以我们改小一点
但也不能太小,否则和直接算就一样了
所以我们用一个新的东西来存
下面来看一个图
注意到这里的C和我们之前的S很像
那我们就这样处理
用C来记一个和,但不是前缀和,而是类似与前缀和
仔细看这个图,如果我们要求前缀和,从C一直向右走,把走到的所有C加起来就是S
query解决了
再来看add
再看这个图,如果我们要更新一个点,从C一直向左走,把走到的所有C都加d就行了
那我们应该怎么走呢
先介绍一个东西lowbit
lowbit(x)的意思就是把x变为2进制
然后将2进制最右边的1的左边截去所得到的值
举一个例子
lowbit(14)
14的二进制是1110
然后将2进制最右边的1的左边截去
得到10
所以lowbit(14)=2
在计算时我们用下面的代码
inline int lowbit(int x){ return x&-x;}
如果我们已经走到了i点
要向左走就到 i+lowbit(i)
要想右走就到 i -lowbit(i)
ps:如果想不通的话画一下就明白了
然后我们来实现这两个操作
add(x,d)
void add(int x,int d){ int cur=x; while(cur<=n){ C[cur]+=d; cur+=lowbit(cur); }}
然后再实现求前缀和
int sum(int pos){ int s=0; int cur=pos; while(cur>0){ s+=C[cur]; cur-=lowbit(cur); }return s;}
在实现query就很容易了
int query(int l,int r){ return sum(r)-sum(l-1);}
如何初始化呢,add(i,A[i])就行呢
最后我们来分析一下复杂度,add和query都是O(log n)
因为每次都让规模减小了半
而预处理的复杂度是O(nlog n)
于是我们可以用O(nlog n)来预处理
O(log n)来维护和更新
用这样的规模来解决这个问题
ps:当然还可以用线段树,不过在这个问题上BIT已经够用了
pps:注意下标
- Fenwick Tree
- Binary Indexed Tree(BIT) OR Fenwick Tree
- 树状数组/Binary Indexed Tree/Fenwick Tree
- POJ 3321 Apple Tree DFS序+fenwick
- 树状数组(Fenwick tree,又名binary indexed tree
- Fenwick tree (CF Educational Codeforces Round 10)
- [LeetCode]--327. Count of Range Sum && Merge_Sort && Fenwick Tree
- Codeforces Gym 100623F Problem F. Fenwick Tree
- 简单了解一下 Segment Tree 和 Fenwick Tree(Binary Indexed Tree)
- 【面试常见算法整理】Binary Indexed Tree(Fenwick Tree,树状数组)详解
- ACM ICPC 2008–2009, NEERC, Problem F Fenwick Tree(找规律,打表) Codeforces Gym 100623F
- 2维fenwick树
- UVa12532 - Interval Product(Fenwick树)
- UVa12086 - Potentiometers(树状数组即Fenwick树)
- LA 4329 - Ping pong 树状数组(Fenwick树)
- LA 5902 - Movie collection 树状数组(Fenwick树)
- Uva 1428 Ping pong (树状数组,Fenwick树)
- poj 2299 Ultra-QuickSort(fenwick树求逆序对)
- php打印前一天时间格式
- 在Eclipse 中下载 开源中国码云上的项目
- 公共数据库介绍~google公共数据
- 在mac上安装gradle(2017.6.5)
- 自学Java之Java编程(输入和输出)(015day)
- Fenwick Tree
- 92 C语言指针变量的运算
- Android
- 通孔焊盘制作教程
- 【stm32f407】SysTick实现延时
- 几个hive用到的命令
- java for循环和while
- TreeMap 嵌套
- D