树状数组讲解(简洁好懂)
树状数组
树状数组是用于维护前缀和的数据结构,支持单点的查询和修改,如果要修改区间的值则需要用到差分数组。数字太大时可以在排序后进行离散化。
树状数组原理详解:
首先我们需要知道lowbit(x)是返回x的最后一个1,例如二进制数10100就返回100.
树状数组的核心思想是将一个数分解成若干零件,在维护的时候,直接对这些零件进行处理,在查询的时候再将这些零件组装成我们想要的数。
我们先来看看树状数组是如何查询的:
ll query(int p)
{ll ans = 0;for (; p; p -= lowbit(p))ans += f[p];return ans;
}
仔细观察可以发现,查询的过程是将数p进行了二进制分解。
例如:二进制数p为1101,我们就要将它分解为:
1101
1100
1000
分解的方式是减去上一个数的最后一个1
那么,为什么这种分解方式是正确的呢,也就是要证明这些零件包含了p之前前的每一个数,并且值包含一次。
然后我们在观察它的插入过程:
void insert(int p, int k)
{for (; p <= n; p += lowbit(p))f[p] += k;
}
可以发现如下规律:
以4位二进制数为例
从0001到1000的数都会被累加到1000当中
从1001到1100的数都会被累加到1100当中
从1101到1110的数都会被累加到1110当中
1111单独加到1111当中
例如0110->1000,0101->0110->1000,1010->1100
这些1000,1100,1110,1111就是所有的零件,所有的前缀和都可以由他们组合得到,并且不重不漏,他们的特点是加上lowbit后会变成10000,也就是他们最终会统合到10000中,所有小于等于10000的数都会被统计到10000中,所以我们也递归地证明了所有小于等于1000的数会统计到1000当中。加上lowbit操作本质上是产生进位,填补lowbit位后的第一个0,然后把这个0后面的位都变成0,而从0001到0111中,第一位都是0,所以在不断加上lowbit后,一定会到达1000这个数,把值传给他。1001到1011也是一样,第二位总是0,在不断加上lowbit后,一定会把第二位变成1,也就是1100。而1000,1100,1110,1111均可视为01000,01100,01110,01111,他们的第一位也总是0,所以一定会累加到10000当中,也就通过lowbit形成了一棵树,我们称其为树状数组。
树状数组讲解(简洁好懂)相关推荐
- 树状数组 讲解和题目集
树状数组 树状数组作为一种实现简单.应用较广的高级数据结构,在OI界的地位越来越重要,下面我来简单介绍一下树状数组和它的简单应用. 一.树状数组简介 树状数组:顾名思义,是一种数组,其中包含了树的思想 ...
- 8.26树状数组讲解
今天又看了一遍博客,温故知新,说说新的理解,树状数组的题型主要有,单点更新,区间查询:区间更新,单点查询:区间更新,区间查询:求逆序数(边插边)求和的思路得掌握好, 当是sum(0-sum()时,先写 ...
- 集训8.21树状数组讲解
有点想家了... 树状数组的用途:单点更新,区间查询(如敌兵布阵) 区间更新,单点查询(如color the ball) 一维树状数组: int lowbit(int x) { return ...
- hdu-1166敌兵布阵(树状数组)
此处的树状数组讲解请点击:here~~~ #include<stdio.h> #include<string.h> int n,a[50005],q[40005]; int l ...
- 树状数组(详细分析+应用),看不懂打死我!
树状数组介绍 在学习一个算法之前一定要清楚它能干嘛,能解决什么样的问题,对你解题是否有帮助,然后才去学习它! 那么接下来看如下几个问题 什么是树状数组 顾名思义就是一个结构为树形结构的数组,于二叉树的 ...
- 树状数组萌新讲解+基础习题【一点一滴】
树状数组基础篇 树状数组讲点 中文名:树状数组 英文名:Binary Indexeds Tree 英译中:二进制索引树 这特么多清楚 引入: 给你n个数 1. 求区间的的和 2. 改变某个值 然后朴素 ...
- 树状数组(单点+区间的所有操作)
转载:https://blog.csdn.net/I_believe_CWJ/article/details/80374326 更简洁方便的数据结构--树状数组(基于线段树的实现) 1.单点更新+区间 ...
- 树状数组简单易懂的详解
树状数组确实是个好东西啊,以前搞比赛的时候了解过它,会套用模版,但确没有深入理解这个东西,先学会用轮子,然后再学造轮子嘛,这段时间再回头研究了一下,发现二进制在算法中真的是的好东西,它可以使算法的时间 ...
- BZOJ1901Zju2112 Dynamic Rankings——树状数组套主席树
题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1 ],a[i+2]--a[j]中第k小的数是多少(1≤k ...
最新文章
- 例5-17和例5-18
- java异常的总接口_重构:Java特别的接口修改:在throws子句中添加一个异常?
- python vimIDE环境
- pandas的dataframe
- 【Java】 环境变量如何配置?
- Silverlight4启动无法调试
- 计算机网络简历自我认识,计算机网络专业简历的自我评价
- 英语魔法师之语法俱乐部阅读笔记
- 微信公众号开发三 测试号申请
- 堪称神器的Chrome插件!
- YYT 0664 - 2008 医疗器械软件 软件生存周期过程
- python libusb_libusb介绍和使用示例
- 适配2K和4K分辨率
- PC免费简约开源的TXT小说阅读器(提取章节、书籍分组管理、记忆阅读进度、换肤、换字体、换主题)仅支持Windows
- HashMap 深拷贝
- cuckoo sandbox安装
- 如何为数据库服务器配置存储和内存(转载)
- 瘦客户服务器哪个系统最好,云终端和瘦客户机的区别以及优缺点分析
- 一维扩散方程差分格式的数值计算
- 自己收集的一些逆向工程的入门概念——壳、注册机、算法求逆、反病毒、免杀