题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
Sample Input 1 10 1 2 3 4 5 6 7 8 9 10 Query 1 3 Add 3 6 Query 2 7 Sub 10 2 Add 6 3 Query 3 10 End Sample Output Case 1: 6 33 59
分析:这是典型的更新线段上的一个点然后查询线段上的区间的和,算是线段树的模版应用题目了,因为只有点更新,所有再找点的时候所有的节点都进行了更新,看线段树代码之前先把建树的图弄懂,然后就是模板了
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<queue> 5 #include<algorithm> 6 #include<time.h> 7 using namespace std; 8 9 const int maxn = 2005; 10 const int N=1000007; 11 12 #define lson rt<<1///rt*2 13 #define rson rt<<1|1///rt*2+1 14 15 int A[N]; 16 17 struct node 18 { 19 int l,r,s; 20 }tree[N<<2]; 21 22 void build(int l,int r,int rt) 23 { 24 tree[rt].l=l; 25 tree[rt].r=r; 26 27 if(l==r) 28 { 29 tree[rt].s=A[l]; 30 return ; 31 } 32 33 int mid=(l+r)/2; 34 35 build(l,mid,lson); 36 build(mid+1,r,rson); 37 38 tree[rt].s=tree[lson].s+tree[rson].s;///求和 39 } 40 41 void update(int pos,int val, int rt) 42 { 43 tree[rt].s+=val;///加减更新 44 45 if(tree[rt].l==tree[rt].r) 46 return ; 47 48 int mid = (tree[rt].l+tree[rt].r)/2; 49 50 if(pos<=mid) 51 update(pos,val,lson); 52 else 53 update(pos,val,rson); 54 } 55 56 int query(int l,int r,int rt) 57 { 58 if(tree[rt].l==l&&tree[rt].r==r) 59 return tree[rt].s; 60 61 int mid = (tree[rt].l+tree[rt].r)/2; 62 63 if(r<=mid) 64 return query(l,r,lson); 65 else if(l>mid) 66 return query(l,r,rson); 67 else 68 { 69 int lsum,rsum; 70 lsum=query(l,mid,lson); 71 rsum=query(mid+1,r,rson); 72 return lsum+rsum; 73 } 74 } 75 76 int main() 77 { 78 int T,i,a,b,n,c=1; 79 char s[100]; 80 81 scanf("%d", &T); 82 83 while(T--) 84 { 85 scanf("%d", &n); 86 printf("Case %d: ", c++);///别落了 87 88 for(i=1;i<=n;i++) 89 scanf("%d", &A[i]); 90 91 build(1,n,1); 92 93 while(scanf("%s", s),strcmp(s,"End")) 94 { 95 if(s[0]=='Q') 96 { 97 scanf("%d %d", &a,&b); 98 printf("%d ",query(a,b,1)); 99 continue; 100 } 101 int f=1; 102 scanf("%d%d", &a,&b); 103 if(s[0]=='S') 104 f*=-1; 105 update(a,b*f,1); 106 } 107 } 108 return 0; 109 }