在codevs上有模板题目,虽说是线段树模板,不过就题目描述来说,树状数组轻松水过
传送门:http://codevs.cn/problem/1080/
能用线段树就不要用平衡树,能用树状数组就不要用线段树,这话是显然的,代码长度、难道上都有较大区别,BIT是最简单的一个
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 8 using namespace std; 9 10 typedef long long ll; 11 12 const int Size = 23333333; 13 14 int n; 15 int a[Size], bit[Size], sum[Size]; 16 // a为初始读入的数组 17 // bit为树状数组的本身 18 // sum[i]为前i项和 19 20 void addbit(int,int);//即在树状数组上做单点修改 21 int sumbit(int);//求出前n项和 22 23 int main(){ 24 scanf("%d",&n); 25 for (int i = 1;i <= n; ++ i){ 26 scanf("%d",&a[i]); 27 sum[i] = sum[i - 1] + a[i]; 28 // 对于每个点都addbit的话太浪费时间,所以初始时记录前n项和,之后的求和只要用到修改内容即可 29 } 30 int m,x,y,c; 31 for (scanf("%d",&m);m;m--){ 32 scanf("%d",&c); 33 if (c == 1){ 34 scanf("%d%d",&x,&y); 35 addbit(x,y); 36 } 37 else{ 38 scanf("%d%d",&x,&y); 39 // 注意是x-1,而不是x,因为包括x点 40 int ans=sum[y]-sum[x-1];//对于初始数据的x~y的和 41 ans+=sumbit(y)-sumbit(x-1);//对于改变数据x~y的和 42 printf("%d\n",ans); 43 } 44 } 45 return 0; 46 } 47 48 void addbit(int x,int delta){ 49 for (;x <= n;x += x & -x)//运用lowbit进行二进制的快速运算; 50 bit[x]+=delta; 51 } 52 53 int sumbit(int x){ 54 int ans=0; 55 for (;x;x -= x & -x) 56 ans += bit[x]; 57 return ans; 58 }
时间: 2024-11-16 09:10:30