树状数组模板
【模板】树状数组 1 点我
代码:
#include <iostream> using namespace std; int c[500001],n,m,t1,t2,t3; int lowbit(int x) { return x&-x; } void update(int x,int k) { for(int i=x;i<=n;i+=lowbit(i)) c[i]+=k; } int sum(int x) { int ans=0; for(int i=x;i>0;i-=lowbit(i)) ans+=c[i]; return ans; } int main() { cin >> n >> m; for(int i=1;i<=n;i++) { cin >> t1; update(i,t1); } for(int i=1;i<=m;i++) { cin >> t1 >> t2 >> t3; if(t1==1) update(t2,t3); if(t1==2) cout << sum(t3)-sum(t2-1) << endl; } return 0; }
【模板】树状数组 2 点我
代码:
#include <iostream> using namespace std; int c[500001],n,m,t1,t2,t3,t4; int lowbit(int x) { return x&-x; } void update(int l,int r,int k) { for(int i=l;i<=n;i+=lowbit(i)) c[i]+=k; for(int i=r+1;i<=n;i+=lowbit(i)) c[i]-=k; } int sum(int x) { int ans=0; for(int i=x;i>0;i-=lowbit(i)) ans+=c[i]; return ans; } int main() { cin >> n >> m; for(int i=1;i<=n;i++) { cin >> t1; update(i,i,t1); } for(int i=1;i<=m;i++) { cin >> t1 >> t2; if(t1==1) { cin >> t3 >> t4; update(t2,t3,t4); } if(t1==2) cout << sum(t2) << endl; } return 0; }
关于lowbit:
大家看看这张图,我列举出了各个元素的lowbit值。我们可以发现,lowbit(x)=father(x)-x。father[x]代表x的父亲(比如图中1的父亲是2,3的父亲是4,6的父亲是8)。
另外我们还可以发现,lowbit(x)=x-lastbrother(x)。lastbrother(x)代表x的前一个兄弟。如果x是第一个兄弟,则lastbrother(x)=0。
比如图中4的前一个兄弟是0,6的前一个兄弟是4,7的前一个兄弟是6。
树状数组在没有区间max的情况下可以代替线段树,比线段树快的不知道 哪里去了
具体看代码
#include<bits/stdc++.h> using namespace std; #define maxn 100000 #define lowbit(x) ((x)&(-(x))) int n,m,t,x,y; long long w; struct tagTreeArray { long long c[maxn],a[maxn];//前者存i*a[i],后者存差分 void upd(int x,long long k)//x...inf区间加一个数 { for(int i=x;i<=n;i+=lowbit(i)) { c[i]+=x*k; a[i]+=k; } } long long query(int x)//查询1...x区间和 { long long ans1=0,ans2=0; for(int i=x;i>0;i-=lowbit(i)) { ans1+=a[i]; ans2+=c[i]; } return ans1*(x+1)-ans2; } void add(int l,int r,long long k)//[l,r]加一个数 { upd(l,k); upd(r+1,-k); } long long query(int l,int r)//查询l...r区间和 { return query(r)-query(l-1); } }arr; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%lld",&x); arr.add(i,i,x); } for(int i=1;i<=m;i++) { scanf("%d",&t); if(t==1) { scanf("%d%d%lld",&x,&y,&w); arr.add(x,y,w); } if(t==2) { scanf("%d%d",&x,&y); printf("%lld\n",arr.query(x,y)); } } }