【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵
https://vjudge.net/contest/66989#problem/A
单点修改,区间查询
方法一:线段树
http://www.cnblogs.com/kuangbin/archive/2011/08/15/2139834.html
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<cstdlib> 8 9 using namespace std; 10 const int maxn=5e4+5; 11 const int inf=0x3f3f3f3f; 12 int num[maxn]; 13 int n; 14 struct Node 15 { 16 int l; 17 int r; 18 int nSum; 19 }segTree[maxn<<2]; 20 21 void Build(int i,int l,int r) 22 { 23 segTree[i].l=l; 24 segTree[i].r=r; 25 if(l==r) 26 { 27 segTree[i].nSum=num[l]; 28 return; 29 } 30 int mid=(l+r)>>1; 31 Build(i<<1,l,mid); 32 Build((i<<1)|1,mid+1,r); 33 segTree[i].nSum=segTree[i<<1].nSum+segTree[(i<<1)|1].nSum; 34 } 35 36 void Add(int i,int t,int b) 37 { 38 segTree[i].nSum+=b; 39 if(segTree[i].l==segTree[i].r) 40 { 41 return; 42 } 43 int mid=(segTree[i].l+segTree[i].r)>>1; 44 if(t<=mid) 45 { 46 Add(i<<1,t,b); 47 } 48 else 49 { 50 Add((i<<1)|1,t,b); 51 } 52 } 53 54 int Query(int i,int l,int r) 55 { 56 if(segTree[i].l==l&&segTree[i].r==r) 57 { 58 return segTree[i].nSum; 59 } 60 int mid=(segTree[i].l+segTree[i].r)>>1; 61 if(r<=mid) 62 { 63 return Query(i<<1,l,r); 64 } 65 else if(l>mid) 66 { 67 return Query((i<<1)|1,l,r); 68 } 69 else 70 { 71 return Query(i<<1,l,mid)+Query((i<<1)|1,mid+1,r); 72 } 73 } 74 int main() 75 { 76 int T; 77 scanf("%d",&T); 78 int kas=1; 79 while(T--) 80 { 81 printf("Case %d:\n",kas++); 82 scanf("%d",&n); 83 for(int i=1;i<=n;i++) 84 { 85 scanf("%d",&num[i]); 86 } 87 Build(1,1,n); 88 char ch[20]; 89 int a,b; 90 while(scanf("%s",ch)==1&&ch[0]!='E') 91 { 92 scanf("%d%d",&a,&b); 93 if(ch[0]=='Q') 94 { 95 int ans=Query(1,a,b); 96 printf("%d\n",ans); 97 } 98 else if(ch[0]=='A') 99 { 100 Add(1,a,b); 101 } 102 else 103 { 104 Add(1,a,-b); 105 } 106 } 107 } 108 return 0; 109 }
方法二:树状数组
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<cstdlib> 8 9 using namespace std; 10 const int maxn=5e4+5; 11 const int inf=0x3f3f3f3f; 12 int tree[maxn]; 13 int n; 14 void Init() 15 { 16 memset(tree,0,sizeof(tree)); 17 } 18 int lowbit(int x) 19 { 20 return x&-x; 21 } 22 23 void Add(int i,int x) 24 { 25 while(i<=n) 26 { 27 tree[i]+=x; 28 i+=lowbit(i); 29 } 30 } 31 32 int Query(int i) 33 { 34 int res=0; 35 while(i) 36 { 37 res+=tree[i]; 38 i-=lowbit(i); 39 } 40 return res; 41 } 42 43 void Setval(int i,int x) 44 { 45 int v=Query(i)-Query(i-1); 46 Add(i,-v); 47 Add(i,x); 48 } 49 50 int Query(int l,int r) 51 { 52 return Query(r)-Query(l-1); 53 } 54 55 int main() 56 { 57 int T; 58 scanf("%d",&T); 59 for(int kas=1;kas<=T;kas++) 60 { 61 Init(); 62 scanf("%d",&n); 63 int x; 64 for(int i=1;i<=n;i++) 65 { 66 scanf("%d",&x); 67 Add(i,x); 68 } 69 printf("Case %d:\n",kas); 70 char ch[20]; 71 int a,b; 72 while(scanf("%s",ch)==1&&ch[0]!='E') 73 { 74 scanf("%d%d",&a,&b); 75 if(ch[0]=='A') 76 { 77 Add(a,b); 78 } 79 else if(ch[0]=='S') 80 { 81 Add(a,-b); 82 } 83 else 84 { 85 int ans=Query(a,b); 86 printf("%d\n",ans); 87 } 88 } 89 } 90 return 0; 91 }