树状数组
来源:互联网 发布:java面试吹牛 编辑:程序博客网 时间:2024/05/29 17:13
树状数组在我刚学时没有熟练掌握,半年后重温树状数组,感觉好了很多。
它是这样的:
假设数组a[1..n],那么查询a[1]+...+a[n]的时间是log级别的,而且是一个在线的数据结构,支持随时修改某个元素的值,复杂度也为log级别。
来观察这个图:
令这棵树的结点编号为C1,C2...Cn。令每个结点的值为这棵树的值的总和,那么容易发现:
C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
...
C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16
这里有一个有趣的性质:
设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax,
所以很明显:Cn = A(n – 2^k + 1) + ... + An
这样我们就可以用位运算来解决。
x=x&(x^(x-1));
利用补码可化为
x=x&-x;
用c语言可以实现点修改和区间查询这两个操作。
(1)点修改:
void update(int x,int delta){while(x<=n){c[x]+=delta;x+=x&-x;}}(2)区间查询:
int query(int x){int sum=0;while(x){sum+=c[x];x-=x&-x;}return sum;}十多行代码,把查询O(n^2)降为O(nlogn),好算法,可以复杂问题简单化,对比线段树来说更方便调试.
阅读全文
0 0
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 开源项目:购物软件的开发
- shiro学习笔记
- Linux编程预习-函数
- Leetcode 695. Max Area of Island
- 【网络编程】TCP状态转换图(重点)
- 树状数组
- python之正则(re)
- Nginx + Tomcat 负载均衡配置
- CodeVS4730 特殊等式-1@2@3@...@(N-1)=N
- hadoop 学习笔记005(shell命令简单了解)
- GPU的工作原理
- pom配置文件---ssh(学习笔记)
- 单点登录
- Java内存分配