C81【模板】树状数组 点修+区查 区修+点查
C81【模板】树状数组 点修+区查 区修+点查_哔哩哔哩_bilibili
树状数组是一种支持 单点加 和 区间查 的,代码量小的数据结构.
普通树状数组维护的信息及运算要满足 结合律 且 可差分,如加法(和)、乘法(积)、异或等.
树状数组能解决的问题是线段树能解决的问题的子集.树状数组代码短,常数小.
在差分数组和辅助数组的帮助下,树状数组还可解决更强的 区间加 单点查 和 区间加 区间和 问题.
树状数组的拿手绝活——“点加+区查(区间和)” 和 “区加(点差分)+点查(前缀和)”



P3374 【模板】树状数组 1 - 洛谷
// 树状数组 点加+区和 O(nlogn) #include<bits/stdc++.h> using namespace std; const int N=500010; int n,m; struct BIT{ int c[N]; //区间和 void upd(int x,int w){ //向后修 for(;x<=n;x+=x&-x) c[x]+=w; } int ask(int x){ //向前查,前缀和 int s=0; for(;x;x-=x&-x) s+=c[x]; return s; } }B; int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1,k;i<=n;i++) cin>>k, B.upd(i,k); //初值 for(int i=1,op,x,y,k;i<=m;i++){ cin>>op>>x; if(op==1) cin>>k, B.upd(x,k); //点修 else cin>>y, cout<<B.ask(y)-B.ask(x-1)<<"\n"; //区查 } }
// 树状数组 区加(点差分)+前缀和 O(nlogn) #include<bits/stdc++.h> using namespace std; const int N=500010; int n,m,a[N]; struct BIT{ int c[N]; //差分的区间和 void upd(int x,int w){ for(;x<=n;x+=x&-x) c[x]+=w; } void upd(int x,int y,int w){ upd(x,w); upd(y,-w); //点差分 } int ask(int x){ //前缀和 int s=a[x]; //初值 for(;x;x-=x&-x) s+=c[x]; return s; } }B; int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1,op,x,y,k; i<=m; i++){ cin>>op>>x; if(op==1){ cin>>y>>k; B.upd(x,y+1,k); //区修 } else cout<<B.ask(x)<<"\n"; //点查 } }
浙公网安备 33010602011771号