数据结构和算法 - 树状数组
2022/4/5 1:19:28
本文主要是介绍数据结构和算法 - 树状数组,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
树状数组
1. 问题
序号 | 题目 |
---|---|
—— | —————————————————————————————————————————————————————— |
307. 区域和检索 - 数组可修改 | |
493. 翻转对 | |
HDU P1166 敌兵布阵 |
给定一个数组\(A\),长度为\(n\),数组的下标范围是\([0,n-1]\),对数组A可进行:
- 查询\([i,j]\)区间内的和;
- 对位置\(i\)的值,加一个值\(x\);
常规解决思路:抽象为“区间和查询”和“区间更新”问题,
- 模拟,操作1的时间复杂度是\(O(n)\),操作2的时间复杂度是\(O(1)\);
- 前缀和,操作1的时间复杂度是\(O(1)\),操作2的时间复杂度是\(O(n)\);
2. 定义
为了平衡操作1和操作2,引进了树状数组\(C\),即每个位置i表示原始数组的一个区间,值\(C[i]\)表示的是原始数组\(A\)中\([i-lowbit(i)+1, i]\)区间之和,其中\(lowbit(i)\) 表示数字i的二进制表示中,位数最低的1所代表的值,如:
\[\begin{array}{l} 1 -> [0] \\ 2 -> [1,2] \\ 3 -> [3] \\ 4 -> [1,2,3,4] \\ i -> [i-lowbit(i)+1, i] \\ \end{array} \]个人理解:最低位的1的位置表示区间的长度,如\((1000)_{2}\)表示\([1,8]\)的区间。
3. 操作
- 二进制位
- 区间添加
- 区间查询
class TreeArray{ vector<int> tr; vector<int> nums; int n; int lowBit(int x){ return x & -x; } void add(int x, int u){ for(int i=x; i<=n; i+=lowBit(i)){ tr[i] += u; } } int query(int x){ int ans = 0; for(int i=x; i> 0; i -= lowBit(i)){ ans += tr[i]; } return ans; } // 初始化 // for(int i=0; i< n;i++){ // add(i+1, nums[i]); //} // 区间和 // sumRange: query(right+1) - query(left); };
4. 复杂度
时间复杂度:\(O(\log(n))\)
空间复杂度:\(O(n)\)
这篇关于数据结构和算法 - 树状数组的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南