js 数组 实现 完全树_算法和数据结构 | 树状数组(Binary Indexed Tree)
本文来源于力扣圈子,作者:胡小旭。点击查看原文
力扣leetcode-cn.com
树状数组或二叉索引树(英语:Binary Indexed Tree),又以其发明者命名为 Fenwick 树。其初衷是解决数据压缩里的累积频率(Cumulative Frequency)的计算问题,现多用于高效计算数列的前缀和, 区间和。它可以以
文章先介绍低位运算(lowbit)的基本知识,再提及如何将一个整数划分为
lowbit(低位)运算
比如:
公式
如何计算一个整数
中二进制表示下所有位是 1 的数值?
比如
朴素算法需要枚举整数中所有的位,时间复杂度为
为了高效获取二进制表示下所有位是 1 的数值,可以利用
比如
为了得到
代码
C++ 实现
const MAX_N = 1 << 20;
int H[MAX_N + 1];
for (int i = 0; i <= 20; ++i) H[1 << i] = i;
while (cin >> n) {while (n > 0) {cout << H[n & -n] << ' ';n -= n & -n;}cout << endl;
}
树状数组
假设整数
那么,可以将区间 [1,n] 划分成
- ...
比如,
利用
C++ 实现
while (x > 0) {printf("[%d, %d]n" x - lowbit(x) + 1, x);x -= lowbit(x);
}
树状数组是基于以上思想的数据结构,基本用途是维护序列的前缀和。
那么,假设有序列
此时,以树形结构展开的序列 A 中的每一个节点都对应着树状数组中的一个值。那么这个值为以当前节点为根的子树中所有节点值的总和。
接着,我们看下以树形结构展开的树状数组是什么样的。
Index
代表序列A
中元素的索引,为了方便,以 1 为起点计数Original Value
代表序列A
中的元素值BIT Value(Binary Indexed Tree Value)
代表树状数组中的值Binary bit
代表索引值的二进制形式Low bit
代表索引值的二进制形式下的地位
上图中最大的区别是某些节点中的值发生了变化。这是因为,在以树形结构展开的树状数组中的每一个值代表的是一个区间的总和。这个区间即为我们上述求解的区间,比如一个整数 7,可以将其划分成
比如
再比如
基本操作
树状数组支持两个基本操作——查询前缀和,单点增加。
查询前缀和
在寻求序列 A 的前 n 项的前缀和时,等于
C++ 实现
int query(int x) {int ans = 0;for (; x; x -= x & -x) ans += bit[x];return ans;
}
单点增加
观察父子节点的关系,可以推算出,父节点的索引 parent(i),为其子节点索引值 + 其低位——
C++ 实现
void update(int x, int delta) {for (; x; x += x & -x) bit[x] += delta;
}
关于查询前缀和与单点增加的计算过程,可以观看下面视频展示的动画。
树状数组与逆序对
对于一个序列
- 逆序遍历序列
- 利用树状数组的性质,使用
操作获取每一个元素的逆序对数
- 将当前元素更新
到树状数组中
- 循环迭代上述步骤,直到遍历所有元素
C++ 实现
int cnt = 0;
for (int i = A.size() - 1; i >= 0; --i) {cnt += query(A[i]);update(A[i], 1);
}
在每一次更新
在每一次获取
注意,上述的求解过程时,如果序列A的值范围较大时,那么需要离散化处理。
参考
- 《算法竞赛进阶指南》
- 维基百科——树状数组
本文作者:胡小旭
声明:本文归作者版权所有,如需转载请联系。文中图片和视频为作者“胡小旭”制作,未经允许严禁修改和翻版使用。
js 数组 实现 完全树_算法和数据结构 | 树状数组(Binary Indexed Tree)相关推荐
- 数据结构——树状数组
我们今天来讲一个应用比较广泛的数据结构--树状数组 它可以在O(nlogn)的复杂度下进行单点修改区间查询,下面我会分成三个模块对树状数组进行详细的解说,分别是树状数组基本操作.树状数组区间修改单点查 ...
- 树状数组 java_算法模板之树状数组
什么是树状数组? 树状数组就是通过数组来模拟一种树形结构,这种树形结构能够维护区间信息.同样类似的数据结构还有线段树,线段树与树状数组相比,它的结点更多,也就是说线段树的常数更大. 线段树是通过把 ...
- 数据结构--树状数组
文章目录 1. 树状数组 2. 单点修改 3. 区间修改 4. 完整代码 5. 参考文献 1. 树状数组 类似数据结构:线段树(Segment Tree) 树状数组 跟 线段树 的区别: 树状数组能做 ...
- 2017西安交大ACM小学期数据结构 [树状数组 离散化]
Problem E 发布时间: 2017年6月28日 12:53 最后更新: 2017年6月29日 21:35 时间限制: 1000ms 内存限制: 64M 描述 给定一个长度为n的序列a ...
- 2017西安交大ACM小学期数据结构 [树状数组,极大值]
Problem D 发布时间: 2017年6月28日 10:51 最后更新: 2017年6月28日 16:38 时间限制: 1000ms 内存限制: 32M 描述 给定一个长度为n的序列a ...
- 2017西安交大ACM小学期数据结构 [树状数组]
Problem C 发布时间: 2017年6月28日 11:38 最后更新: 2017年6月28日 16:38 时间限制: 1000ms 内存限制: 32M 描述 给定一个长度为n的序列a ...
- 数据结构 —— 树状数组
[概述] 树状数组又称二叉索引树,常用于高效计算数列的前缀和.区间和,其查询.修改的时间复杂度为 log(n),空间复杂度为 O(n) 树状数组通过将线性结构转化成树状结构,从而进行跳跃式扫描. 优点 ...
- Java数据结构-树状数组
什么是树状数组?[面试5.0] 使用数组表示多叉树的结构,和优先队列有点类似,区别在于优先队列只表示二叉树 主要用来: 更新数组元素的数值并且求数组前K个元素的总和或平均值 时间复杂度为O(logN) ...
- poi 1990 MooFest(树状数组题目,转换成两个树状数组来做)较难的题目****
1.http://poj.org/problem?id=1990 2.题目大意: 题意:FJ有n头牛,排列成一条直线(不会在同一个点),给出每头牛在直线上的坐标x.另外,每头牛还有一个自己的声调w,如 ...
最新文章
- Pymol(1.8.6)作图技巧之cartoon和surface镶嵌模型
- angularjs 元素重复指定次数_5.2 设置循环次数:for +range 句式
- word2vec的通俗理解
- 请求因 HTTP 状态 401 失败:Unauthorized。
- 【OS学习笔记】十 实模式:实现一个程序加载器-程序加载器如何将用户程序加载到内存并执行
- POJ 1273 Drainage Ditches 最大流
- 《Python编程从入门到实践》记录之类编码风格
- 软件测试适合女生学吗?
- 报表性能优化方案之多种报表服务器内存修改方法
- 传统ORB-SLam中位姿优化中雅克比矩阵讲解
- bootstrapValidator常用验证规则总结
- 计算机操作系统-设备驱动实现实验报告
- python 读取pdf图片_Python提取PDF第一页为封面图片【批量提取】
- 互联网知识变现,不起眼利润高的冷门行业有哪些?
- android studio红色下划线,如何在Android Studio中为文字加下划线?
- PHP学习线路图:四个阶段
- 腾讯云服务器和阿里云服务器新客选谁
- 如何在openlayers中使用iconfont或font Awesome字体图标
- 15张超详细的Python学习路线图,纯良心分享,零基础学习宝典
- 关于页面请求发起后,通过F12查看到,被挂起页面中stalled花费很长时间问题的追查...
热门文章
- 每天学习python 30分钟 -了解python - 看懂#!/usr/bin/python
- 【双边滤波】基于小波变换的多尺度自适应THZ增强双边滤波器的MATLAB仿真
- 基于SNN脉冲神经网络的FPGA实现介绍
- 『Lucas定理以及拓展Lucas』
- Python字符串、时间戳、datetime时间相关转换
- LVS负载均衡群集的了解与基本配置(一)
- VMware vSphere Client安装Centos7
- swift UI专项训练4 场景过渡-转场
- android支持第三方jar包,以及Eclipse如何导入jar包
- 笨办法学Python——学习笔记1