树状数组一点心得

树状数组的基本概念不说了,网上大佬们的讲解博客很多。

 

先上一段我的模板

inline int lowbit(int x) {return x&-x;}
inline void update(int x,int val){
    for (int i=x; i<maxn; i+=lowbit(i))  tree[i]+=val;
}
inline int Query(int x){
    int res=0;
    for (int i=x; i; i-=lowbit(i))
        res+=tree[i];
    return res;
}

举两个例子来加深一下对树状数组的理解。

可以知道维护的 tree 数组 表示到第 i 项的前缀和。

那么第一个例子就是利用树状数组求解逆序数问题。

给定一个长度为 n 的序列, 对于每个 a[i] 我们简单离散化一下,按从小到大给每个位置编个号 ,假设最小的数对应1,最大的数对应 n ,那么对于新序列,对于每个位置的编号,我们 update(cnt[i])    (cnt[i] 表示该位的编号),那么到从cnt[i] 到比他大的位置都能通过lowbit更新。 我们利用Query函数可以查询到小于该位的数的个数,通过 Query(n) - Query(cnt[i])即可得到 第 i 位产生的逆序数。

一个例题就是奇数码问题:

https://blog.csdn.net/acerkoo/article/details/81124737

 

另一个例子是利用树状数组求连续区间内不同数的个数问题。

详见:

https://blog.csdn.net/acerkoo/article/details/81124576

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值