数据结构 --- 树状数组

树状数组:是一个数据结构

  • 基本用途:维护序列的前缀和

作用:

  1. 快速求前缀和(时间复杂度:O(logn))
  2. 修改某一个数(时间复杂度:O(logn))

lowbit函数

  • 整数在二进制表示下最低位1的位数
int lowbit(int x){
      return x & -x;
}

建树

      //原树状数组
        scanf("%lld %lld",&n,&m);
	for(int i = 1; i <= n; i ++ ){
		scanf("%lld",&x);
		add(i,x);		
	}
      //差分树状数组
        scanf("%lld %lld",&n,&m);
	ll now = 0;
	for(int i = 1; i <= n; i ++ ){
		ll x;
		scanf("%lld",&x);
		add(i,x - now);
		now = x;		
	}

主要操作:

  1. 单点修改:
  • 给序列中的一个数tr[x]加上y,同时正确维护序列的前缀和
void add(int x,int c){
	for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}

  1. 区间查询:
int sum(int x){
	int res = 0;
	for(int i = x; i; i-=lowbit(i)) res+=tr[i];
	return res;
}
  1. 区间修改:
  • 利用差分思想,对于区间修改
      建树有所不同,建立差分树状数组
      add(l,x);add(r + 1,-x);
  1. 单点查询
  • 利用差分思想,对差分数组求前缀和等于原数组
  sum(x);
  • 更新过程是每次加了个二进制的低位1(101+1 ->110, 110 + 10 -> 1000, 1000 + 1000 -> 10000)
  • 查询过程每次就是去掉了二进制中的低位1(1111 - 1 -> 1110, 1110 - 10 -> 1100, 1100 - 100 -> 1000)

posted @ 2020-09-04 16:51  chstor  阅读(122)  评论(0编辑  收藏  举报