树状数组
Posted shzyk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组相关的知识,希望对你有一定的参考价值。
主要要注意lowbit函数
然后add时向右跑,check时向左跑(此处的add只能单点修改)
#include<iostream>//从洛谷3374直接复制来的 #include<cstdio> using namespace std; #define lowbit(x) (x&(-(x))) void read(int &x); int n,m; int a[500005]; void add(int s,int t)//给s+t { int ss=s; for(;ss<=n;ss+=lowbit(ss)) a[ss]+=t; } int check(int s,int t)//左闭右闭 { int res=0; int ret=0; int ss=s-1; int tt=t; for(;tt;tt-=lowbit(tt)) ret+=a[tt]; for(;ss;ss-=lowbit(ss)) res+=a[ss]; return ret-res; } int main() { Read(n),Read(m); int w; for(int i=1;i<=n;i++) Read(w),add(i,w); for(int i=1;i<=m;i++) { int e,s,t; RRead(e),Read(s),Read(t); if(e==1) add(s,t); if(e==2) printf("%d ",check(s,t)); } return 0; } void Read(int &x) { x=0; char c=getchar(); int i=1; while(c<‘0‘ or c>‘9‘) { if(c==‘-‘) i=-1; c=getchar(); } while(c>=‘0‘ and c<=‘9‘) { x=x*10+c-‘0‘; c=getchar(); } x*=i; }
若想实现区间修改,则要结合差分(不过这就只能单点查询了)
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define lowbit(x) ((x)&(-(x))) 5 void read(int &x); 6 int n,m; 7 int a[500005]; 8 int c[500005]; 9 void add(int s,int t)//给s+t 10 { 11 int ss=s; 12 for(;ss<=n;ss+=lowbit(ss)) a[ss]+=t; 13 } 14 int check(int s,int t)//左闭右闭 15 { 16 int res=0; 17 int ret=0; 18 int ss=s-1; 19 int tt=t; 20 for(;tt;tt-=lowbit(tt)) ret+=a[tt]; 21 for(;ss;ss-=lowbit(ss)) res+=a[ss]; 22 return ret-res; 23 } 24 int main() 25 { 26 read(n),read(m); 27 c[0]=0; 28 for(int i=1;i<=n;i++) read(c[i]); 29 for(int i=n;i>=1;i--) c[i]=c[i]-c[i-1]; 30 //for(int i=1;i<=n;i++) printf("*%d",a[i]); 31 for(int i=1;i<=n;i++) add(i,c[i]); 32 //for(int i=1;i<=n;i++) printf("*%d",check(1,i)); 33 for(int i=1;i<=m;i++) 34 { 35 int e,r; 36 read(e); 37 if(e==1) 38 { 39 int x,y,z; 40 read(x),read(y),read(z); 41 add(x,z); 42 add(y+1,(z*(-1))); 43 } 44 if(e==2) read(r),printf("%d ",check(1,r)); 45 } 46 return 0; 47 } 48 void read(int &x) 49 { 50 x=0; 51 char c=getchar(); 52 int i=1; 53 while(c<‘0‘ or c>‘9‘) 54 { 55 if(c==‘-‘) i=-1; 56 c=getchar(); 57 } 58 while(c>=‘0‘ and c<=‘9‘) 59 { 60 x=x*10+c-‘0‘; 61 c=getchar(); 62 } 63 x*=i; 64 }
所以最强大的还是线段树了
以上是关于树状数组的主要内容,如果未能解决你的问题,请参考以下文章