树状数组:优雅而简短的数据结构
学习树状数组:http://blog.youkuaiyun.com/int64ago/article/details/7429868(安利一篇特别好的博文,非常的详细)
模板:
//更新树状数组
void add(int k,int num)//k是数组下标,num为变化数值的大小
{
while(k<=n) //n是数组的大小
{
tree[k]+=num;
k+=k&-k;//lowbit(k),比如10100得出来的就是100 11101000得出来的就是1000
}
}
//求和 1~k
int read(int k)
{
int sum=0;
while(k){
sum+=tree[k];
k-=k&-k;
}
return sum;
}
//区间更新
int update(int x,int y,int num)
{
add(x,num);
add(y+1,-num);
}
//区间求解最值,a数组是原序列,c是储存该区间最大值的数组
int lowbit(int x)
{
return x&-x;
}
//改变只能从最左边的数字开始改变
void change(int r) {
c[r] = a[r];
for(int i = 1; i < lowbit(r); i <<= 1)
c[r] = max(c[r], c[r-i]);
}
//查询得出结果
int getmax(int l, int r) {
int ret = a[r];
while(l <= r) {
ret = max(ret, a[r]);
for(--r; r - l >= lowbit(r); r -= lowbit(r))
ret = max(ret, c[r]);
}
return ret;
}