【复习】【树状数组】

一、lowbit

int lowbit(int x) {
     return x&(-x)}

作用:

取出十进制数x二进制表示中由最低位往最高位方向的第一个1
如10的二进制为 ( 1010 ) 2 (1010)_2 (1010)2
取出由最低位往最高位方向的第一个1:
( 10 ) 2 (10)_2 (10)2
即为数字2

这个时候我们如果将原数x减去这个数的lowbit,在二进制的表示当中,我们就消除了由最低位往最高位方向的第一个1

原理

首先了解一下负数的二进制表示:
计算机二进制中为了区分正负数,在最高位上进行区分:最高位为0则为正数,最高位为1则为负数
比如用八位二进制表示一个负数,那么最高位第八位一定是1

正数二进制转对应负数二进制的方法:
将正数二进制中的非最高位的部分全部取反,然后非最高位的部分+1,最后最高位为1直接与处理后的非最高位的部分合并,就得到了对应负数的二进制。
如:
13的8位二进制为: ( 00001101 ) 2 (00001101)_2 (00001101)2
非最高位的部分全部取反: ( 1110010 ) 2 (1110010)_2 (1110010)2
非最高位的部分+1: ( 1110011 ) 2 (1110011)_2 (1110011)2
最高位为1与处理后的非最高位合并: ( 11110011 ) 2 (11110011)_2 (11110011)2
-13的8位二进制表示即为 ( 11110011 ) 2 (11110011)_2 (11110011)2
再比如:
20的8位二进制位 ( 00010100 ) 2 (00010100)_2 (00010100)2
-20的8位二进制位 ( 01101100 ) 2 (01101100)_2 (01101100)2

多举几个例子,我们发现一个规律:
正数与一个负数进行与运算&,最后得到的结果总是这个正数由最低位往最高位方向的第一个1。
联系一下求负数的二进制的方法,就很容易懂了。

二、求和、修改
这个地方涉及树状数组的原理,由于博主在此处只是作为一个复习的笔记,不过多赘述。
求前缀和[1,x]代码:

int getsum(int x) {
     
	int sum=0;
	while(x>=0) {
     
		sum+=c[x];
		x-=lowbit(x);
	} 
	return sum;
}

单点修改a[x]+y

void update(int x,int y) {
     
	while(x<=n) {
     
		c[x]+=y;
		x+=lowbit(x);
	}
}

你可能感兴趣的:(复习,数据结构-树状数组)