- 2022tysc0250 的博客
树·状数组
- 2023-11-25 15:44:52 @
一个很优美的东西。主要用于在动态数组中求区间和。
关于 lowbit()
指的是 的二进制表达式中最右边 所对应的值。即 与上 的值。
证明:
的值 | 的值 | 的值(补码) | & 后的值 |
---|---|---|---|
可以发现, 为奇数时,,否则, 最后一个 后面一堆 。因为偶数二进制补码最后一位一定是 ,就会有进位。
树
根据 lowbit()
建树。若要查询一个节点 的关系节点:
-
父节点:
- 若 为左儿子,就将 ;
- 若为右儿子,则 。
-
儿子节点:
- 左儿子:;
- 右儿子:。
代码
若要修改某个值,则需要将其关联的区间全部修改。
需要从下往上爬,不断找右上方的节点(不一定按照边找父亲)。途径的每个节点都需要加上给出的值。最终一直加到 以后才结束。
void modify(int x,int d)//修改
{
while(x <= n)
{
c[x] += d;
x += lowbit(x);
}
return;
}
若要查询和,则不停找左上角的值。但要保证现在的节点编号大于 。
int sum(int x)//求和
{
int dig = 0;
while(x >= 1)
{
dig += c[x];
x -= lowbit(x);
}
return dig;
}
综合:
int lowbit(int x)//函数
{
return x & (-x);
}
void modify(int x,int d)
{
while(x <= maxn)
{
c[x] += d;
x += lowbit(x);
}
return;
}
int sum(int x)
{
int dig = 0;
while(x >= 1)
{
dig += c[x];
x -= lowbit(x);
}
return dig;
}