当前位置:网站首页>树状数组
树状数组
2022-07-17 08:31:00 【casperwu】
树状数组
1. 定义
树状数组是一种动态维护数组前缀和、区间和的数据结构。其思想和跳变类似: 添加索引, 高效维护数组。

2. 构建树状数组思路
任意一个正整数可以唯一分解为若干个不重复的2次幂之和。如: 7 = 2^2 + 2^1 + 2^0, 12 = 2^3 + 2^2
基于二进制的思想, C[k]表示的就是k的二进制表示下的最低位的1以及后面的0组成的数的长度。因此c[12] = a[12] + a[11] + a[10] + a[9]。
lowbit(x) 定义为: x二进制下最低位的1和后面的0组成的数值(等价于x 二进制分解下的最小次幂)。
2.1 树状数组的性质
每个内部节点c[x] 保存以它为根的子树中所有叶节点的和。除树根外,每个内部节点c[x] 的父节点是c[x + lowbit(x)]。
2.2 树状数组的查询操作
int query(int x) { // 查询前缀和(前x个数据的和)
int ans = 0;
for(; x > 0; x -= x & -x) ans += c[x];
return ans;
}
2.3 树状数组的更新操作
void add(int x, int delta) { // 第 x 个数加上 delta
for(; x <= N; x += x & -x) c[x] += delta;
}
3. 模板题目
3.1 代码
class NumArray {
public:
NumArray(vector<int>& nums) {
n = nums.size();
a = vector<int>(n + 1, 0);
c = vector<int>(n + 1, 0);
for(int i = 1; i <= n; i++) {
a[i] = nums[i - 1];
add(i, nums[i - 1]);
}
}
void update(int index, int val) {
++index; // 因为将原数组往后移动了一位
int delta = val - a[index];
add(index, delta);
a[index] = val;
}
int sumRange(int left, int right) {
return query(right + 1) - query(left);
}
private:
int n;
vector<int> a; // 原数组
vector<int> c; // 树状数组
int query(int x) {
int ans = 0;
for(; x > 0; x -= lowbit(x)) ans += c[x];
return ans;
}
void add(int x, int delta) {
for(; x <= n; x += lowbit(x)) c[x] += delta;
}
int lowbit(int x) {
return x & -x;
}
};
边栏推荐
- 深度学习第四周Key Concepts on Deep Neural Networks习题整理
- 使用arduino开发esp8266和esp32时首选项设置方法
- 【CTF】pwn2_sctf_2016
- 2022 Guangdong Provincial Safety Officer a certificate, the third batch (main person in charge) exercise questions and mock examination
- Li Kou 43 string multiplication note
- Build an embedded development environment
- 【LeetCode】通用操作总结
- Distributed transaction reliable message final consistency solution
- 百度Apoll
- Project code training tutorial
猜你喜欢

深度学习第一周Introduction to Deep Learning习题整理

力扣382链表随机节点笔记

Eureka Basics

使用arduino开发esp8266和esp32时首选项设置方法

【Port 3000 is already in use,3000端口被占用问题解决方法】

mongodb $符号的神奇用法+mongo数据类型

石墨厚度测量

2022t elevator repair examination question bank and answers

Redis publishing and subscription

Leetcode sword finger offer II 041 Average value of sliding window: low space consumption solution
随机推荐
scratch逆序输出 电子学会图形化编程scratch等级考试四级真题和答案解析2022年6月
id Tech5的MegaTexture技术
【LeetCode】通用操作总结
Introduction to deep learning exercises sorting in the first week of deep learning
JS learning notes 09-12: prototype objects, foreach+tostring and recycle bin
Redis common data types - hash and ordered set Zset (sorted set)
【AXI】解读AXI协议的额外信号(QOS信号,REGION信号,与USER信号)
力扣455分发饼干笔记
MySQL中查询一个字符串字段的值不为空到底该怎么写?
LeetCode 0116.填充每个节点的下一个右侧节点指针
Consul service registration and discovery
石墨厚度测量
The latest generation of Internet: Web 3.0
Xgen hair guide history cleared solution
Baidu Apollo
动态内存管理
为什么别人游戏里的特效都非常柔和
JS learning notes 06-08: traversal of arrays and four methods of arrays
半透明双层玻璃侧厚
2022t elevator repair examination question bank and answers