hdu1166(线段树单点更新&区间求和模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

 

题意:中文题诶~

 

思路:线段树单点更新,区间求和模板

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #define lson l, mid, rt << 1
 4 #define rson mid + 1, r, rt << 1 | 1
 5 using namespace std;
 6 
 7 const int MAXN = 5e4 + 10;
 8 int sum[MAXN << 2];
 9 
10 void push_up(int rt){//向上求和
11     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
12 }
13 
14 //建树
15 void build(int l, int r, int rt){//sum[rt] 对应区间 [l, r] 的和
16     if(l == r){
17         scanf("%d", &sum[rt]);
18         return;
19     }
20     int mid = (l + r) >> 1;
21     build(lson);
22     build(rson);
23     push_up(rt);//向上更新节点
24 }
25 
26 //单点更新
27 void updata(int p, int add, int l, int r, int rt){//在p点增加add
28     if(l == r){//找到p点
29         sum[rt] += add;//单点更新
30         return;
31     }
32     int mid = (l + r) >> 1;
33     if(p <= mid) updata(p, add, lson);
34     else updata(p, add, rson);
35     push_up(rt);//向上更新节点
36 }
37 
38 //区间求和
39 int query(int L, int R, int l, int r, int rt){//对[L, R]区间求和
40     if(L <= l && R >= r) return sum[rt];//当前区间[l, r]包含在求和区间[L, R]中
41     int ans = 0;
42     int mid = (l + r) >> 1;
43     if(L <= mid) ans += query(L, R, lson);//L在mid左边
44     if(R > mid) ans += query(L, R, rson);//R在mid右边
45     return ans;
46 }
47 
48 int main(void){
49     int t, n;
50     scanf("%d", &t);
51     for(int i = 1; i <= t; i++){
52         printf("Case %d:\n", i);
53         scanf("%d", &n);
54         build(1, n, 1);
55         char s[7];
56         while(scanf("%s", s) && s[0] != 'E'){
57             int x, y;
58             scanf("%d%d", &x, &y);
59             if(s[0] == 'Q') printf("%d\n", query(x, y, 1, n, 1));
60             else if(s[0] == 'A') updata(x, y, 1, n, 1);
61             else updata(x, -y, 1, n, 1);
62         }
63     }
64     return 0;
65 }
View Code

 

posted @ 2017-06-07 11:53  geloutingyu  阅读(180)  评论(0编辑  收藏  举报