树状数组一点心得

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

 

先上一段我的模板

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

posted @ 2018-07-20 00:03  Acerkoo  阅读(150)  评论(0编辑  收藏  举报