树状数组
为了表述方便,下面所有的数字,都是二进制形式下的。
拆分成特殊区间------C[i]的定义
树状数组通过特定将区间 [ 1 , i ] \left[1,i \right] [1,i]通过一个特殊地规则,将区间拆分成 k ( k ≤ log 2 i + 1 ) k(k \leq \log_{2}{i+1}) k(k≤log2i+1)个区间 ( i k − 1 , i k ] , ( i k − 2 , i k − 1 ] , … , ( 0 , i 1 ] ] \left(i_{k-1},i_{k} \right], \left(i_{k-2},i_{k-1} \right],\dots,\left(0,i_1\right]] (ik−1,ik],(ik−2,ik−1],…,(0,i1]],其中 i k = i i_k=i ik=i.
而所谓特殊地规则,是这样的,首先将 ( l , r ] \left(l,r\right] (l,r],首先将 r r r用二进制表示,然后将最后一个1变成0即获得了左端点 l l l.
之后把 l l l作为下一个区间的右端点,重复进行,直到整个区间分完了。
举个例子。假设 r = 100011001001 r=100011001001 r=100011001001.划分的区间如下
l | r |
---|---|
100011001000 | 100011001001 |
100011000000 | 100011001000 |
100010000000 | 100011000000 |
100000000000 | 100010000000 |
000000000000 | 100000000000 |
我们将数 i i i二进制表示形式下最后一个1的位权(即那个1及其后面的一连串的0表示的数)定义为 l o w b i t ( i ) lowbit(i) lowbit(i).那么上面拆分成的特殊区间 ( l , r ] \left(l,r\right] (l,r]拆分规则就可以用 l = r − l o w b i t ( r ) = r l o w b i t ( r ) l=r-lowbit(r)=r^lowbit(r) l=r−lowbit(r)=rlowbit(r)表示了。
由位运算的知识不难推导出 l o w b i t ( x ) = x & ( − x ) lowbit(x)=x\&(-x) lowbit(x)=x&(−x).
可以看到,区间的右端点每次变化的时候,都是去掉一个1.因此,拆分成的子区间数就是i二进制表示下1的个数。假设 i i i含有 k k k个1,而 k k k个1表示的最小数是 11 … 1 11\ldots1 11…1,即 2 k − 1 2^k-1 2k−1,故 i ≥ 2 k − 1 i \geq 2^k-1 i≥2