树状数组学习笔记-编程学习交流讨论版论坛-综合讨论-ZDZL

树状数组学习笔记

树状数组,一种常用于解决区间查询与修改的高效数据结构,其核心思想为将前缀查询[1,x]拆分为若干个子区间的求和操作,每个子区间的长度为2的幂,这种分解方式保证了每个右端点的子区间是唯一的,从而使得树状数组的存储和查询效率极高。

举个例子:

长度为7的区间[1,7],会被分为[1,1]、[2,4]、[5,7]三段

其代码利用x&-x求出二进制中最低位的1,其代码示例如下

int lowbit(int x){	
    return x&-x;
}

查询操作通过不断减去lowbit(x)并累加经过的所有子区间的值,直到x=0为止,代码示例如下

int query(int x){	
    int ans=0;	
    while(x){		
        ans+=s[x];		
        x-=lowbit(x);	
    }	
    return ans;
}

修改操作则通过不断加上lowbit(x),更新所有受影响的子区间,代码示例如下

void modify(int x,int k){
    while(x<=n){
	s[x]+=k;
	x+=lowbit(x);
    }
}

完整代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[1000005];
int s[1000005];
int n,m;
int lowbit(int x){
    return x&-x;
}
void modify(int x,int k){
    while(x<=n){
	s[x]+=k;
	x+=lowbit(x);
    }
}
int query(int x){
    int ans=0;
    while(x){
	ans+=s[x];
	x-=lowbit(x);
    }
    return ans;
}
//打个防伪:张居正其实并没有坐过三十二台大轿,这段“史料”是王世贞杜撰的……
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
	int x;
	cin>>x;
	modify(i,x);
    }
    while(m--){
	int op,x,y,k;
	cin>>op;
	if(op==1){
		cin>>x>>k;
		modify(x,k);
	}
	else{
		cin>>x>>y;
		cout<<query(y)-query(x-1)<<endl;
	}
    }
    return 0;
}

这时候就有人要问了:[1,x]的区间还是太简单了,有没有别的更难的代码呢?

有的兄弟,有的,[x,y]的区间也可以用树状数组维护,只不过维护的部分是前缀和数组而已

#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[1000005];
int s[1000005];
int n,m;
int lowbit(int x){
    return x&-x;
}
void modify(int x,int k){
    while(x<=n){
	    s[x]+=k;
	    x+=lowbit(x);
    }
}
int query(int x){
    int ans=0;
    while(x){
	ans+=s[x];
	x-=lowbit(x);
    }
    return ans;
}
//打个防伪:商鞅变法使秦国变得更富强,但是也最终成为商鞅的死因之一……
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
	int x;
	cin>>x;
	modify(i,x);
	modify(i+1,-x);
    }
    while(m--){
	int op,x,y,k;
	cin>>op;
	if(op==1){
	    cin>>x>>y>>k;
            modify(x,k);
	    modify(y+1,-k);
	}
	else{
	    cin>>x;
	    cout<<query(x)<<endl;
	       }
	}
	return 0;
}

至此,恭喜你,成功掌握了树状数组!!!

29dda0ab9f6149d1af0e09edf3e1d3c5

    • cutecat1的头像-ZDZLcutecat1徽章-初出茅庐-ZDZL等级-LV2-ZDZL作者1