mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
52 字
1 分钟
数据结构-树状数组
2026-09-10

核心定位操作lowbit#

#define lowbit(x)((x)&(-(x)))

基本操作#

// 添加操作
void add(ll i,ll x){
while(i<=n){
tree[i]+=x;
i+=lowbit(i);
}
}
// 求和操作
ll sum(ll i){
ll ans=0;
while(i>0){
ans+=tree[i];
i-=lowbit(i);
}
return ans;
}
// 区间查询操作
ll query(ll l,ll r){
return sum(r)-sum(l-1);
}
// 初始化
for(int i=1;i<=n;i++){
ll v;
cin>>v;
add(i,v);
}

模板链接#

例题#

P1908 逆序对 - 洛谷#

int n;
ll cnt;
vector<ll> arr,tree;
void add(ll i,ll x,ll len){
while(i<=len){
tree[i]+=x;
i+=lowbit(i);
}
}
ll sum(ll i){
ll ans=0;
while(i>0){
ans+=tree[i];
i-=lowbit(i);
}
return ans;
}
void solve() {
cin>>n;
arr.resize(n);
vector<int> ls;
for(int i=0;i<n;i++){
cin>>arr[i];
ls.push_back(arr[i]);
}
sort(ls.begin(),ls.end());
ls.erase(unique(ls.begin(),ls.end()),ls.end());
int m=ls.size();
tree.assign(m+1,0LL);
for(int i=n-1;i>=0;i--){
int it=lower_bound(ls.begin(),ls.end(),arr[i])-ls.begin()+1;
cnt+=sum(it-1);
add(it,1,m);
}
cout<<cnt;
}

4.受限交换【算法赛】 - 蓝桥云课#

int n;
ll cnt;
vector<ll> arr,b;
ll tree[N],pos[N];
void add(ll i,ll x){
while(i<=n){
tree[i]+=x;
i+=lowbit(i);
}
}
ll sum(ll i){
ll ans=0;
while(i>0){
ans+=tree[i];
i-=lowbit(i);
}
return ans;
}
void solve() {
cin>>n;
arr.assign(n+1,0);
b.assign(n+1,0);
for(int i=1;i<=n;i++){
cin>>arr[i];
pos[arr[i]]=i;
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
for(int i=n;i>=1;i--){
int curp=pos[b[i]];
cnt+=sum(curp-1);
add(curp,1);
}
cout<<cnt;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

数据结构-树状数组
https://blog.hydrodyio.xyz/posts/数据结构-树状数组/
作者
Hydroiody
发布于
2026-09-10
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录