【洛谷 p3368】模板-树状数组 2(数据结构)
题目:已知一个数列,你需要进行下面两种操作:1.将某区间每一个数数加上x;2.求出某一个数的和。
解法:树状数组+前缀和优化。数组中每位存和前一位的数的差,这样区间修改只用改两位,单点询问就是求前缀和。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 const int N=500010; 8 int n; 9 int c[N]; 10 11 int lowbit(int x) {return x&-x;} 12 void ins(int x,int d) 13 { 14 for (int i=x;i<=n;i+=lowbit(i)) 15 c[i]+=d; 16 } 17 int query(int x) 18 { 19 int h=0; 20 for (int i=x;i>=1;i-=lowbit(i)) 21 h+=c[i]; 22 return h; 23 } 24 int main() 25 { 26 int m,x,y,k; 27 scanf("%d%d",&n,&m); 28 y=0; 29 for (int i=1;i<=n;i++) 30 { 31 scanf("%d",&x); 32 ins(i,x-y); 33 y=x; 34 } 35 while (m--) 36 { 37 scanf("%d",&k); 38 if (k==1) 39 { 40 scanf("%d%d%d",&x,&y,&k); 41 if (x>y) {int t;t=x,x=y,y=t;} 42 ins(x,k),ins(y+1,-k); 43 } 44 else 45 { 46 scanf("%d",&x); 47 printf("%d\n",query(x)); 48 } 49 } 50 return 0; 51 }