树状数组是解决快速更新以及统计数组某段区间总和,设一个数组A[1-N],需要计算A[M-K]的总和,暴力解法需要O(K-M),如果我们求出sum(1-K)和sum(1-M),那么答案就是sum(1-M)-sum(1-K);

那么如何快速求出sum(1-N),可以考虑直接求,但如果我们再加一个条件,需要即时更新,那么使用暴力解法就会出现问题,假设更新A[K],需要对sum(1-K)到sum(1-N)进行更新,这是一个非常费时的过程。

这里我们使用一种二进制的思想,我们将十进制转为二进制进行举例思考,如上图,

C[0001] = A[0001];

C[0010] = A[0010] + A[0001];

C[0011] = A[0011];

C[0100] = A[0100] + A[0011] + A[0010] + A[0001];

C[0101] = A[0101];

C[0110] = A[0110] + A[0101];

C[0111] = A[0111];

C[1000] = A[1000] + A[0111] + A[0110] + A[0101] + A[0100] + A[0011] + A[0010] + A[0001];

把k定义为末尾连续0个数,可以理解为C[i] = A[i] + ... + A[i-2^k+1]。

更新的过程就是更新与A[i]相关的C[j],举例说明:i = 0001,j = 0001, 0010, 0100, 1000,i = 0101, j = 0110, 1000;不难看出有不断进位的规律。

求sum得过程就是求取每一位1所对应的数字的C[i]和,举例说明:

sum[1-1111] = C[1111] + C[1110] + C[1100] + C[1000];

  C[1111] = A[1111];

  C[1110] = A[1110] + A[1101];

  C[1100] = A[1100] + A[1011] + A[1010] + A[1001];

  C[1000] = A[1000] + A[0111] + A[0110] + A[0101] + A[0100] + A[0011] + A[0010] + A[0001];

了解了树状数组所具有的二进制规律,那么下来考虑如何用代码实现。

int lowbit(x) {return x&-x;
}void update(int k,int x) {for(int i=k;i<=n;i+=lowbit(i)) {C[i]+=x; }
} 

0001 -> 0010, 即 0001 + 0001 = 0010;

0010 -> 0100, 即 0010 + 0010 = 0100;

0101 -> 0110, 即 0101 + 0001 = 0110;

0110 -> 1000, 即 0110 + 0010 = 1000;

lowbit函数就是求取所加的最小进位数,x&-x可以这样理解:-x表示补码,举例可证原码&补码等于最小进位数。

更新过程就是for循环从更新的k开始,将所有C数组中相关元素更新。

int getsum(int x)
{int ans=0;for(int i=x;i;i-=lowbit(i))//i要大于0ans+=C[i];return ans;
}

1111 -> 1110, 即 1111 - 0001 = 1110;

1110 -> 1100, 即 1110 - 0010 = 1100;

1100 -> 1000, 即 1100 - 0100 = 1000;

1000 -> 0000, 即 1000 - 1000 = 0000;

同理可以看出求和是通过减去最小进位数,得到下一个需要加的值。

转载于:https://www.cnblogs.com/ACMessi/p/8469339.html

树状数组-神奇的二进制相关推荐

  1. HDU 5869.Different GCD Subarray Query-区间gcd+树状数组 (神奇的标记右移操作) (2016年ICPC大连网络赛)...

    树状数组... Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/6 ...

  2. 树状数组原理及经典应用问题

    树状数组 对于数组相信大家并不陌生,那么为什么要在数组前面加上'树状'二字呢? 数组是一种存储结构,树状数组是一种逻辑结构,它巧妙的应用了二进制的某些性质,使得数组的某些区间查询和修改变得非常的快,就 ...

  3. 【学习笔记+习题集】(树状数组)(9473字)

    目录 板块一:树状数组 引子:lowbit 1.存入数据(单点修改) 2.区间查询 练习1:hdoj1541 3.区间修改和单点查询(差分数组) 练习1:hdoj 1556 练习2:洛谷P3368 4 ...

  4. szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】

    树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...

  5. 【数据结构】树状数组详解(Leetcode.315)

    前言 最近做题时遇到一个关于树状数组的题力扣https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/但是CSDN上仅有 ...

  6. 【模板】一维树状数组

    ACM模板 目录 聊聊前缀和 什么是树状数组? 树状数组相关操作 局限性 差分在树状数组中的应用 区间更新.单点查询 区间更新.区间查询 树状数组应用 聊聊前缀和 比如数组 int a[7]={1,2 ...

  7. b+树时间复杂度_前端大神用的学习笔记:线段树和树状数组

    全文篇幅较长,细心理解一定会有收获的♪(^∇^*). 1|0线段树 1|1一些概念     线段树是一种二叉搜索树,每一个结点都是一个区间(也可以叫作线段,可以有单点的叶子结点),有一张比较形象的图如 ...

  8. 树状数组(求逆序对)

    一.树状数组是什么 树状数组,又称二进制索引树,英文名Binary Indexed Tree 之前遇到一个求逆序对的题,看了很多题解都只说了这个树状数组,关于怎么实现的全都避而不谈,我研究了一下午,总 ...

  9. P4428-[BJOI2018]二进制【树状数组,set】

    正题 题目链接:https://www.luogu.com.cn/problem/P4428 题目大意 长度为nnn的0/10/10/1串要求支持 修改一个位置 求区间[l,r][l,r][l,r]有 ...

最新文章

  1. mysql中存储过程另存为_转: MySQL中的存储过程
  2. pycharm git 超详细教程
  3. RequestDispatcher对象的应用-请求包含
  4. Windows Phone 7知识锦分享【第二季】
  5. Shell脚本学习-阶段四-mysqladmin
  6. 机器学习基础:极大似然估计(Machine Learning Fundamentals: Maximum Likelihood Estimation)
  7. 一个多道批处理系统中仅有 P1 和 P2 两个作业
  8. 免费url长网址缩短压缩工具评测,短链接在线生成器推荐。
  9. 数字 IC 技能拓展(19)带你了解一款 FPGA 开发板
  10. 你不得不看的“互联网+企业购”大趴攻略
  11. chrome提示代理(https://....)要求提供用户名和密码
  12. Redis Client UI工具
  13. R语言,导入XLSX的Excel数据 多sheet
  14. Java忽略返回字段
  15. 浙江移动面试经验(2011)
  16. 用css、html、js模拟操作系统2
  17. 细节!从solar winds黑客入侵事件中看供应链安全
  18. C语言 结构体数组复制
  19. 国内外LiDAR SLAM实验室总结
  20. 聊天室平台搭建【免费下载 无需积分/C币】java、Android、php多平台聊天室源码打包下载

热门文章

  1. 图像多分类——卷积神经网络
  2. linux 特定用户ssh,linux - 如何在登录后将SSH用户限制为一组预定义的命令?
  3. mysql kafka binlog_为什么使用kafka处理mysql binlog?
  4. 成功解决 ProxyError: Conda cannot proceed due to an error in your proxy configuration
  5. python 嵌套型partials(nested partials)的使用
  6. react父子组件通信案例
  7. 一、服务端开发基础(搭建Web服务器、网络基础概念、请求响应流程、配置Apache、静态网站与动态网站)
  8. LeetCode 624. 数组列表中的最大距离
  9. LeetCode 65. 有效数字(逻辑题,难)
  10. ifix的MySQL数据库_iFIX 技术文章:iFIX历史数据库