笔记_树状数组

树状数组

  1. 特点:以特殊的二进制形式作为数组调用与增长。二进制表示中最后一个1及其后面的0作为单次增长的单位( 即lowbit(x) )

操作方法:向上遍历(即前缀和改变)为循环加lowbit(x)

向下遍历(即区间值求和)为循环减lowbit(x)

备注:Lowbit(x):二进制数最后一个1(最右一个1)以及它后面的0

例:lowbit(10110)=10

求法:lowbitx=x&-x

     2 . 结构特点:树状数组不存储单个数据的值,而是以一定规律存储一组数据的前k项值。

(用的是博主“鲜果维他命”的图)

一.数据分为三个等级:奇数,偶数,2的次方数;

二.奇数永远是最底层的基石,他们就表示他们那一个数据的和(他们本身)

三.偶数是大树躯干中的血肉,它们填充着树空荡的树干。

四.奇数通过算法延伸(奇数的末尾永远都是1)成长为上位的偶数(奇数末尾的1,进行加1后到偶数末尾就是10) 它们的成长就是由末尾的1变为10,100,1000,

它们由二进制特殊进位规则影响的,每次相加都是等效于最末尾的1翻倍而末尾翻倍又等效于二进制的进位,(例:0110→1000;0100→1000;0111→1000)这就是二进制独能完成的关键所在。就此,奇数都以2的次方为单位进行成长(每次成长数值上加了2的k次方)

并且,最后会成长为最高层级——2的次方。2的次方数是数的顶冠,它们永远都在树的最外层、最上层,也是所有树往上攀爬最后的归宿——10000000……

同时,无论是进行±lowbit(x)运算进行某种遍历,最终的停下的位置也一定是2的n次方(树的最外层)

例:数组a的前7项和是t[7]+t[6]+t[4]

     3.应用

树状数组以特定规律存储的区间和,在进行数据的区间修改、与查询上有明显的时间优势,通过巧妙的存储与数学规律换来了查询的便捷

例:区间修改,单点查询;单点修改,区间查询

常规的区间修改与查询往往是单点简单,区间复杂(需要遍历区间上的所有元素),而树状数组中和了这两个的复杂度,在略微提高单点操作的难度的条件下,大幅减小区间操作的复杂度

例:单点修改,区间查询:修改a[2]的值,求数组a前7项的和。

还是这张图:

(用的是博主“鲜果维他命”的图)

修改a[2],需要更新t[2]本身和它上面的节点t[2],t[4],t[8];

求前7项的和,则需加上t[7]本身和它下面的节点t[6],t[4];

单点修改代码示例:

int add_dandian(int x,int k)
{
	for(int i=x;i<=n;i+=lowbit(i))
	t[i]+=k;
}

区间求和代码示例:

int ask(x){
	int sum = 0;
	for(int i=x;i;i-=lowbit(i)){
		sum+=t[i];
	}
	return sum;
}

而在具体应用中,树状数组的应用并不是非要找到一整组数据满足这个形式或者形状或者是含义,它仅仅只是一个你用来达成某些目的的工具,它不一定要满足标准中的所有功能和使用方法,而是你对其用途的理解在实战中的投射

它不是一个被高高挂起的标准无暇的花瓶格式

它是一个沾满泥尘、充满你手掌温度、浸染泥土气息的农具。

例题:

(学校平台上之前碰到的题,现在平台好像塌了进不去了,我也不知道来源,只能用以前的截图凑合了)

思路:
数组a存放数组的数字,或者用一个map存数字对应的下标
数组b存放 当前位置的数字-当前位置的下标(就是就是还要移的次数)
这两个数组的初始化可以在一个for内完成
接下来是树状数组
从数字1开始查,找到数组b中数字1的值,然后做符号判断,正数就是区间每个值-1,负数就是区间每个值+1
举个例子,

输入:54321
则:4 2 0 -2 -4.
1: 走4个位置,变成31-1-30
2:走3个位置,变成20-200
3:走2个位置,变成1-1000
4:走1个位置,变成00000
5:不用走

上面54321的例子中,b数组中数字1所对应的值是-4,那么数组b中,1这个下标的前4个下标每个都-1 (也就是区间-4),同时输出4
然后查找到2,此时2对应的位置值变成了-3,做同样的操作,输出3
查找到3,做同样的操作,输出2

应用二

优化差分数组

差分数组是一种通过存储数组相邻项的差值,以此来获取在区间修改上无与伦比的优势。但它随之牺牲的便是极其耗时的单点查询(需要反复的求出前缀和),而经由树状数组模板可以对差分数组进行优化。

树状数组的优势就在反复多次求前缀和的速度上,尽管他的单点增加不易,但用树状数组进行优化可以在少量增加它区间修改耗时的基础上,大幅缩减它单点查询所需的时间,使二者获得更好的平衡——树状数组模板的差分数组。

那么,结论就很明显了。特殊的二进制算法性质让它拥有了与其他数据结构不一样的优越遍历,让他适应一些特殊的活动。这就可能就跟现实里的量子计算机一样吧,虽然它确实是智慧,确实是超乎想象,确实是颠覆时代,但襁褓中的结构和思想也只能在特定的问题上大放异彩。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值