HDU 1166 敌兵布阵 (线段树 单点更新)

题目链接

线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯。。就从这个题开始吧!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 const int maxn = 50000+10;
 8 using namespace std;
 9 int a[maxn], n;
10 struct line
11 {
12     int l, r, val;
13 }tr[maxn<<2];
14 
15 void build(int o, int l, int r)
16 {
17     tr[o].l = l; tr[o].r = r;
18     if(l == r)
19     {
20         tr[o].val = a[l];
21         return;
22     }
23     int mid = (l+r)>>1;
24     build(2*o, l, mid);
25     build(2*o+1, mid+1, r);
26     tr[o].val = tr[2*o].val+tr[2*o+1].val;
27 }
28 int query(int o, int l, int r)
29 {
30    if(tr[o].l==l && tr[o].r==r)
31    return tr[o].val;
32    int mid = (tr[o].l+tr[o].r)>>1;
33    if(r <= mid) query(2*o, l, r);
34    else if(l > mid) query(2*o+1, l, r);
35    else
36        return (query(2*o, l, mid)+query(2*o+1, mid+1, r));
37 }
38 void update(int o, int p, int add)
39 {
40     if(tr[o].l==tr[o].r&&tr[o].l==p)
41     {
42             tr[o].val += add;
43             return;
44     }
45     int mid = (tr[o].l+tr[o].r)>>1;
46     if(p<=mid) update(2*o, p, add);
47     else update(2*o+1, p, add);
48     tr[o].val = tr[2*o].val+tr[2*o+1].val;
49 }
50 int main()
51 {
52     int t, i, ca = 1;
53     int p, add, l, r;
54     char s[20];
55     scanf("%d", &t);
56     while(t--)
57     {
58         scanf("%d", &n);
59         for(i = 1; i <= n; i++)
60         scanf("%d", &a[i]);
61         printf("Case %d:
", ca++);
62 
63         build(1, 1, n);
64         while(~scanf("%s", s))
65         {
66             if(strcmp(s, "End")==0) break;
67             if(s[0]=='Q')
68             {
69                 scanf("%d%d", &l, &r);
70                 printf("%d
", query(1, l, r));
71             }
72             if(s[0]=='A')
73             {
74                 scanf("%d%d", &p, &add);
75                 update(1, p, add);
76             }
77             if(s[0]=='S')
78             {
79                 scanf("%d%d", &p, &add);
80                 update(1, p, -add);
81             }
82         }
83     }
84     return 0;
85 }

注释的代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 const int maxn = 50000+10;
 8 using namespace std;
 9 int a[maxn], n;
10 struct line
11 {
12     int l, r, val;   //val表示该区间的和
13 }tr[maxn<<2];
14 
15 void build(int o, int l, int r) //o代表当前节点编号
16 {
17     tr[o].l = l; tr[o].r = r;
18     if(l == r)
19     {
20         tr[o].val = a[l];
21         return;
22     }
23     int mid = (l+r)>>1;
24     build(2*o, l, mid);
25     build(2*o+1, mid+1, r);
26     tr[o].val = tr[2*o].val+tr[2*o+1].val;  //建树把值从下往上加起来
27 }
28 int query(int o, int l, int r)  //求l到r的和
29 {
30    if(tr[o].l==l && tr[o].r==r) //节点的区间吻合返回
31    return tr[o].val;
32    int mid = (tr[o].l+tr[o].r)>>1;
33    if(r <= mid) query(2*o, l, r);
34    else if(l > mid) query(2*o+1, l, r);
35    else
36        return (query(2*o, l, mid)+query(2*o+1, mid+1, r)); //横跨了区间
37 }
38 void update(int o, int p, int add) //对p节点增加add
39 {
40     if(tr[o].l==tr[o].r&&tr[o].l==p)
41     {
42             tr[o].val += add;
43             return;
44     }
45     int mid = (tr[o].l+tr[o].r)>>1;
46     if(p<=mid) update(2*o, p, add);
47     else update(2*o+1, p, add);
48     tr[o].val = tr[2*o].val+tr[2*o+1].val;  //找到值以后的更新
49 }
50 int main()
51 {
52     int t, i, ca = 1;
53     int p, add, l, r;
54     char s[20];
55     scanf("%d", &t);
56     while(t--)
57     {
58         scanf("%d", &n);
59         for(i = 1; i <= n; i++)
60         scanf("%d", &a[i]);
61         printf("Case %d:
", ca++);
62 
63         build(1, 1, n);
64         while(~scanf("%s", s))
65         {
66             if(strcmp(s, "End")==0) break;
67             if(s[0]=='Q')
68             {
69                 scanf("%d%d", &l, &r);
70                 printf("%d
", query(1, l, r));
71             }
72             if(s[0]=='A')
73             {
74                 scanf("%d%d", &p, &add);
75                 update(1, p, add);
76             }
77             if(s[0]=='S')
78             {
79                 scanf("%d%d", &p, &add);
80                 update(1, p, -add);
81             }
82         }
83     }
84     return 0;
85 }
原文地址:https://www.cnblogs.com/bfshm/p/3890630.html