ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树状数组讲解(简洁好懂)

2021-09-18 14:05:17  阅读:204  来源: 互联网

标签:简洁 10000 数组 树状 lowbit 1100 讲解 1000


树状数组

树状数组是用于维护前缀和的数据结构,支持单点的查询和修改,如果要修改区间的值则需要用到差分数组。数字太大时可以在排序后进行离散化。

树状数组原理详解:

首先我们需要知道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形成了一棵树,我们称其为树状数组。

标签:简洁,10000,数组,树状,lowbit,1100,讲解,1000
来源: https://blog.csdn.net/qwqgood/article/details/120365864

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有