在http://blog.youkuaiyun.com/sheldon761642718/article/details/40406011这篇博客中初步介绍了树状数组的基本用法:快速获得一个不断被修改的数组的在某一个区间上的和。具体的说明在上述博客中有详细介绍了。
经过近几天的学习,发现树状数组不仅可以解决区间求和问题,还能很好的解决区间求最值的问题!(是的,不会线段树也没关系!光有树状数组包就您满意!)好了开始具体介绍这个方法~
用树状数组求区间和就是利用了其灵巧方便的区间划分方法,同样,利用这个区间划分方法是可以求一个序列的最值的。这个需要开一个新的c【】数组来储存在一个区间的最值(以求最小值为例),c【i】表示的就是【i-lowbit【i】+1,i】的最小值。以num【】数组来储存区间的值;
首先要记得对num数组和c数组进行合理初始化;(根据所求最值不同进行不同初始化);
存值的时候要注意一下~
void add(int x, int d)
{
num[x] = d;
while(x <= n)
{
if(c[x] > d)
{
c[x] = d;
}
else
break;
x = x + lowbit(x);
}
}
我们需要注意的就是查询的时候了,如果不在一个区间里面的话就只能在查完这个大区间所有包含的子区间内最小值之后再跟余下的元素挨个比较就行了
int find_c(int l,int r)
{
int ans = num[r];
while(l != r)
{
r--;
while(r - lowbit(r) > l)
{
ans = min(ans, c[r]);
r -= lowbit(r);
}
ans = min(ans, num[r]);
}
return ans;
}
注意一下我们比较的时候是按照逆序查找的来比较的,小心不要拉掉元素;
剩下的工作就只是注意一下输入输出工作就好了~
http://acm.hdu.edu.cn/showproblem.php?pid=1754
一道求区间最大值的题目~看完可以去ac~