洛谷P3374 【模板】树状数组 1
- 单点修改,区间查值。细节看代码
- 代码:
1 #include <bits/stdc++.h> 2 #define nmax 500010 3 4 using namespace std; 5 int n,m; 6 int a[nmax],qz[nmax]={0},c[nmax]; 7 8 inline int lowb(int x){ return x&(-x); } 9 10 void build(){ 11 cin>>n>>m; 12 for (int i=1; i<=n; i++) { 13 scanf("%d",&a[i]); 14 qz[i]=qz[i-1]+a[i]; 15 c[i]=qz[i]-qz[i-lowb(i)]; 16 } 17 } 18 19 inline void add(int x,int k){ 20 a[x]+=k; //这里x+=lowb(x)是走向它父亲节点所以先加后走,判断时是x<=n 21 while(x<=n) { c[x]+=k; x+=lowb(x); } 22 } 23 24 inline int findqz(int x){ //求1~x的和 25 int ans=0; 26 while(x) { ans+=c[x]; x-=lowb(x); } 27 return ans; 28 } 29 30 inline int query(int x,int y) { return findqz(y)-findqz(x-1); } 31 32 int main(){ 33 build(); 34 int b,x,y; 35 for (int i=0; i<m; i++) { 36 scanf("%d%d%d",&b,&x,&y); 37 if(b==1) add(x,y); 38 else printf("%d\n",query(x,y)); 39 } 40 return 0; 41 }
- 写树状数组的感觉比写线段树的感觉好多了~在家里一个人打线段树好无聊,都没有朋友玩,没有女仔玩。打了树状数组发现个个都是位运算,行数又少,超喜欢树状数组的。
洛谷P3368 【模板】树状数组 2
- 区间修改(区间加),单点查值。
- 代码:
1 #include <bits/stdc++.h> 2 #define nmax 500010 3 4 using namespace std; 5 int n,m; 6 int a[nmax],c[nmax]={0}; 7 8 inline int lowb(int x){ return x&(-x); } 9 10 inline void ta(int x,int k){ //把1~x的c[i]都加上k 11 while(x) { c[x]+=k; x-=lowb(x); } 12 } 13 14 inline void add(int x,int y,int k){ 15 ta(x-1,-k); 16 ta(y,k); 17 } 18 19 inline int query(int x) { 20 int tot=a[x]; //得在x还没有变的时候把a[x]给加上 21 while(x<=n) { tot+=c[x]; x+=lowb(x); } 22 return tot; 23 } 24 25 int main(){ 26 cin>>n>>m; 27 for (int i=1; i<=n; i++) scanf("%d",&a[i]); 28 int b,x,y,k; 29 for (int i=0; i<m; i++) { 30 scanf("%d",&b); 31 if(b==1) { 32 scanf("%d%d%d",&x,&y,&k); 33 add(x,y,k); 34 } 35 else { scanf("%d",&x); printf("%d\n",query(x)); } 36 } 37 return 0; 38 }