「学习笔记」树状数组

树状数组

操作

以下代码为树状数组最常用的几个操作

1. l o w b i t \mathrm{lowbit} lowbit

function lowbit(x:longint):int64;
Begin
        exit(x and (-x));
end;

2. 单点修改

procedure replace(x,y:int64);
Var i:int64;
Begin
        i:=x;
        interim[x]:=y;
        while i<=n do
        Begin
                tree[i]:=y;
                i:=i+lowbit(i);
        end;
end;

3. 区间查询

function get_summation(x:longint):int64;
Var i:int64;
Begin
        get_summation:=0;
        i:=x;
        while i>0 do
        Begin
                get_summation:=get_summation+tree[i];
                i:=i-lowbit(i);
        end;
        exit(get_summation);
end;

4.区间极值

function get_maximum(x,y:int64):int64;
Var i:int64;
Begin
        get_maximum:=0;
        i:=y;
        while i>=x do
        Begin
                get_maximum:=max(interim[i],get_maximum);
                i:=i-1;
                while i-lowbit(i)>=x do
                Begin
                        get_maximum:=max(tree[i],get_maximum);
                        i:=i-lowbit(i);
                end;
        end;
        exit(get_maximum);
end;

以及……
区间修改可以树上差分。


概念

树状数组与线段树相似,效率上要比线段树高,但适用性却不如线段树。

定义一个数组 T r e e Tree Tree表示子树的叶子结点的权值之和,这样可以发现到:
T r e e 1 = a 1 Tree_1 = a_1 Tree1=a1

T r e e 2 = a 1 + a 2 Tree_2 = a_1 + a_2 Tree2=a1+a2

T r e e 3 = a 3 Tree_3 = a_3 Tree3=a3

T r e e 4 = a 1 + a 2 + a 3 + a 4 Tree_4 = a_1 + a_2 + a_3 + a_4 Tree4=a1+a2+a3+a4

T r e e 5 = a 5 Tree_5 = a_5 Tree5=a5

T r e e 6 = a 5 + a 6 Tree_6 = a_5 + a_6 Tree6=a5+a6

T r e e 7 = a 7 Tree_7 = a_7 Tree7=a7

T r e e 8 = a 1 + a 2 + a 3 + a 4 + a 5 + a 6 + a 7 + a 8 Tree_8 = a_1 + a_2 + a_3 + a_4 + a_5 + a_6 + a_7 + a_8 Tree8=a1+a2+a3+a4+a5+a6+a7+a8

⋯ \cdots

经过观察可以得出 T r e e i = a i − 2 k + 1 + a i − 2 k + 2 + ⋯ + a i Tree_i = a_{i-2^k+1} + a_{i-2^k+2} + \cdots + a_i Treei=ai2k+1+ai2k+2++ai


l o w b i t \mathrm {lowbit} lowbit 函数的意义是取为 x x x 的二进制表达式中最低位的1所对应的值
树状数组本就是对于二进制的理解&运用,利用 l o w b i t \mathrm {lowbit} lowbit 我们可以快速遍历整棵树。


于是乎,树状数组还可以解决各种关于区间の问题。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值