tr[i]节点存储的是a[i-lowbit(i)+1]+……+a[i],一共lowbit(i)个数字之和。
query的理解:
int query(int k) { int res = 0; for (int i = k; i; i -= lowbit(i)) res += tr[i]; return res; }
每次减去当前的lowbit,就可以退回到上一个区间,直至到0
modify的理解:
void modify(int k, int x) { for (int i = k; i <= n; i += lowbit(i)) tr[i] += x; }
modify的原则就是:调节所有受影响的区间。
1.如果快速切换到包含自己的区间?
根据树状数组的性质,我们可以知道,想要到达一个树中节点的上一层,就是要到达一个lowbit更高的位置,lowbit更低的节点一定和当前节点同一层,lowbit相同的节点一定在上一层的更上方。
因此我们的目标位置就是满足lowbit(k)=lowbit(i)<<1的节点
只需要i+=lowbit(i)就可以实现这个操作。
2.是否保证了不会影响同层级节点?
同层级的节点就是那些满足了这样的k:lowbit(k)<lowbit(i) && k > i
显然,这些节点的覆盖范围的左端点在当前区间的右侧,而他们的直属上层节点w=k+lowbit(k),其覆盖范围的左端点也在当前区间右侧。
综上,modify操作只会修改那些它应该涉及到的节点,除此之外的节点仍保有其原来的值。
标签:树状,int,lowbit,modify,理解,数组,res,节点 From: https://www.cnblogs.com/smartljy/p/18041773