树状数组

来源:互联网 发布:淘宝卖家工具 编辑:程序博客网 时间:2024/06/18 11:24

基本概念

A[1..N]为一个长为N的序列,即对于序列A有以下操作:

1】修改操作:将A[x]的值加上c

2】求和操作:求此时A[l..r]的和。

 

}       原数组a

}       树状数组C

 

 

C1=a1

C2=a1+a2

C3=a3

C4=a1+a2+a3+a4

C5=a5

C6=a5+a6

C7=a7

C8=a1+a2+a3+a4+a5+a6+a7+a8

……

C[X]的含义

C[x]管辖的区间为2^k个元素,其中kx二进制末尾0的个数

C[x] = a[x– 2^k + 1] + … + a[x]

K的计算

 

k的函数代码如下
int Lowbit(int t) 

      return t & ( -t ); 
}

 

快速求和(复杂度logN)

Sum[9] = C[9]+C[8]

Sum[8] = C[8]

Sum[7] = C[7]+C[6]+C[4]

   …..

a[1]—a[end]和的函数代码如下
int Sum(int end) 

      int sum = 0; 
      while(end > 0) 
      { 
          sum += C[end]; 
          end -= Lowbit(end); 
      } 
      return sum; 
}


修改数组a的某个元素值(复杂度logN

例如 a[3]+x

影响C[3], C[4], C[8]

 

void Update(int pos , int num) 

      while(pos <= n) 
      { 
            C[pos] += num; 
            pos += Lowbit(pos); 
      }

}

线段树与树状数组比较

}       树状数组和线段树一样,是一种很高效的数据结构。但是在于空间耗费较小。

}       对于长度为n的线段(区间),线段树需要2n的空间,而树状数组只要n即可。

}       树状数组的另一个优点是编程简单。

}       树状数组的致命缺点是无法记录一些附加信息。

}       比如区间总长度” 就无法用树状数组维护。

}       树状数组的应用范围是很窄的

}       求和的问题可以用树状数组;

}       如果求最大值操作、而且没有删除操作的话,那也能够用树状数组

0 0
原创粉丝点击