敌兵布阵 HDU - 1166 (线段树)

 

 

线段树模板题:

 

  1 #include<iostream>
  2 #include<vector>
  3 #include<string>
  4 #include<cmath>
  5 #include<set>
  6 #include<algorithm>
  7 #include<cstdio>
  8 #include<map>
  9 #include<cstring>
 10 #include<list>
 11 
 12 #define MAXSIZE 50010
 13 
 14 using namespace std;
 15 
 16 int tree[4*MAXSIZE];
 17 int T, N;
 18 char order[100];
 19 
 20 void init()
 21 {
 22     memset(tree, 0, sizeof(tree));
 23 } 
 24 
 25 
 26 void build(int node, int l, int r)
 27 {
 28     if(l == r)    // 到达叶子节点,赋值
 29     {
 30         scanf("%d", &tree[node]);
 31         return;
 32     } 
 33     
 34     int mid = (l+r)/2;
 35     build(node*2, l, mid);
 36     build(node*2+1, mid+1, r);
 37     
 38     tree[node] = tree[node*2] + tree[node*2+1];
 39 }
 40 
 41 // 单点更新
 42 void update(int node, int l, int r, int index, int add)
 43 {
 44     if(l == r)
 45     {
 46         tree[node] += add;    // 更新方式 
 47         return;
 48     }
 49     
 50     int mid = (l+r)/2;
 51     if(index <= mid)    // 进入左子树 
 52         update(node*2, l, mid, index, add);
 53     else                // 进入右子树 
 54         update(node*2+1, mid+1, r, index, add);
 55         
 56     tree[node] = tree[node*2] + tree[node*2 + 1]; 
 57 }
 58 
 59 // 区间查找 
 60 int query_range(int node, int l, int r, int L, int R)
 61 {
 62     if(l <= L && r >= R)
 63         return tree[node];
 64     int mid = (L+R)/2;
 65     int sum = 0;
 66     if(mid >= l)
 67         sum += query_range(node*2, l, r, L, mid);
 68     if(mid < r)
 69         sum += query_range(node*2+1, l, r, mid+1, R);
 70     
 71     return sum;
 72 }
 73 
 74 int main()
 75 {    
 76     scanf("%d", &T);
 77     for(int t = 1; t <= T; ++t)
 78     {
 79         scanf("%d", &N);
 80         init();
 81         build(1, 1, N);
 82         printf("Case %d:\n", t);
 83         while(1)
 84         {
 85             scanf("%s", order);
 86             if(strcmp(order, "End") == 0)
 87                 break;
 88                 
 89             int i, j;
 90             scanf("%d%d", &i, &j);
 91             switch(order[0])
 92             {
 93                 case 'A':
 94                     update(1, 1, N, i, j);
 95                     break;
 96                 case 'S':
 97                     update(1, 1, N, i, -j);
 98                     break;
 99                 case 'Q':
100                     printf("%d\n", query_range(1, i, j, 1, N));
101                     break; 
102             }
103         }
104     }
105 
106     return 0;
107 }

 

 

 

 

  1 #include<iostream>
  2 #include<vector>
  3 #include<string>
  4 #include<cmath>
  5 #include<set>
  6 #include<algorithm>
  7 #include<cstdio>
  8 #include<map>
  9 #include<cstring>
 10 #include<list>
 11 
 12 #define MAXSIZE 50010
 13 
 14 using namespace std;
 15 
 16 int tree[4*MAXSIZE];
 17 int lz[4*MAXSIZE];
 18 int T, N;
 19 char order[100];
 20 
 21 void init()
 22 {
 23     memset(tree, 0, sizeof(tree));
 24     memset(lz, 0, sizeof(lz));
 25 } 
 26 
 27 
 28 void build(int node, int l, int r)
 29 {
 30     if(l == r)    // 到达叶子节点,赋值
 31     {
 32         scanf("%d", &tree[node]);
 33         return;
 34     } 
 35     
 36     int mid = (l+r)/2;
 37     build(node*2, l, mid);
 38     build(node*2+1, mid+1, r);
 39     
 40     tree[node] = tree[node*2] + tree[node*2+1];
 41 }
 42 
 43 
 44 void push_down(int node, int l, int r)
 45 {
 46     if(lz[node])
 47     {
 48         int mid = (l+r)/2;
 49         lz[node*2] += lz[node];
 50         lz[node*2+1] += lz[node];
 51         tree[node*2] += (mid-l+1)*lz[node];
 52         tree[node*2+1] += (r-mid)*lz[node];
 53         lz[node] = 0;
 54     }
 55 }
 56 
 57 // 区间更新,lr为更新范围,LR为线段树范围,add为更新值
 58 void update_range(int node, int l, int r, int L, int R, int add)
 59 {
 60     if(l <= L && r >= R)
 61     {
 62         lz[node] += add;
 63         tree[node] += (R-L+1)*add;    // 更新方式 
 64         return;
 65     }
 66     
 67     push_down(node, L, R);
 68     int mid = (L+R)/2;
 69     if(mid >= l)    // 进入左子树 
 70         update_range(node*2, l, r, L, mid, add);
 71     if(r > mid)        // 进入右子树 
 72         update_range(node*2+1, l, r, mid+1, R, add);
 73         
 74     tree[node] = tree[node*2] + tree[node*2 + 1]; 
 75 }
 76 
 77 // 区间查找 
 78 int query_range(int node, int l, int r, int L, int R)
 79 {
 80     if(l <= L && r >= R)
 81         return tree[node];
 82     push_down(node, L, R);
 83     int mid = (L+R)/2;
 84     int sum = 0;
 85     if(mid >= l)
 86         sum += query_range(node*2, l, r, L, mid);
 87     if(mid < r)
 88         sum += query_range(node*2+1, l, r, mid+1, R);
 89     
 90     return sum;
 91 }
 92 
 93 
 94 void Add(int i, int j)
 95 {
 96     update_range(1, i, i, 1, N, j);
 97 }
 98 
 99 
100 void Sub(int i, int j)
101 {
102     update_range(1, i, i, 1, N, -j);
103 }
104 
105 
106 int Query(int i, int j)
107 {
108     int sum = query_range(1, i, j, 1, N);
109     return sum;
110 }
111 
112 
113 int main()
114 {    
115     scanf("%d", &T);
116     for(int t = 1; t <= T; ++t)
117     {
118         scanf("%d", &N);
119         init();
120         build(1, 1, N);
121         printf("Case %d:\n", t);
122         while(1)
123         {
124             scanf("%s", order);
125             if(strcmp(order, "End") == 0)
126                 break;
127                 
128             int i, j;
129             scanf("%d%d", &i, &j);
130             switch(order[0])
131             {
132                 case 'A':
133                     Add(i, j); 
134                     break;
135                 case 'S':
136                     Sub(i, j); 
137                     break;
138                 case 'Q':
139                     printf("%d\n", Query(i, j));
140                     break; 
141             }
142         }
143     }
144 
145     return 0;
146 }

 

转载于:https://www.cnblogs.com/FengZeng666/p/11445662.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值