HDU 1166 敌兵布阵 线段树的基本应用——动态区间和问题
题目: http://acm.hdu.edu.cn/showproblem.php?pid=1166
简单题,1A了,这个好像就是传说中的“点树”。
设当前结点表示线段[left, right],编号为i,则结点的左孩子表示线段[left, mid], 编号为2*i,右孩子表示线段[mid+1, right], 编号为2*i+1。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 4 const int MAXN = 50000; 5 6 //线段树的结点,分别表示一条线段的左端点、右端点、增加的人数 7 struct Tree_Node 8 { 9 int left; 10 int right; 11 int num; 12 }tree[4*MAXN]; 13 14 //建立线段树,left和right对应线段树结点中的left和right,i表示当前结点的线段树编号 15 void build(int left, int right, int i) 16 { 17 tree[i].left = left; 18 tree[i].right = right; 19 tree[i].num = 0; 20 if(left == right) 21 { 22 return; 23 } 24 int mid = (left + right) / 2; 25 build(left, mid, 2*i); 26 build(mid+1, right, 2*i+1); 27 } 28 29 //插入到线段树,tar表示增加人数的那个点在数轴上的编号(不是在线段树上的编号) 30 //num表示增加的人数,step表示当前结点的线段树编号 31 void insert(int tar, int num, int step) 32 { 33 if(tree[step].left <= tar && tree[step].right >= tar) 34 { 35 tree[step].num += num; 36 } 37 if(tree[step].left == tree[step].right) 38 { 39 return; 40 } 41 int mid = (tree[step].left + tree[step].right) / 2; 42 if(tar <= mid) 43 { 44 insert(tar, num, step*2); 45 } 46 else 47 { 48 insert(tar, num, step*2+1); 49 } 50 } 51 52 //left和right表示查询的区间,step表示当前结点的线段树编号 53 int query(int left, int right, int step) 54 { 55 if(tree[step].left == left && tree[step].right == right) 56 { 57 return tree[step].num; 58 } 59 int mid = (tree[step].left + tree[step].right) / 2; 60 if(right <= mid) 61 { 62 return query(left, right, step*2); 63 } 64 else if(left > mid) 65 { 66 return query(left, right, step*2+1); 67 } 68 else 69 { 70 return query(left, mid, step*2) + query(mid+1, right, step*2+1); 71 } 72 } 73 74 int main() 75 { 76 int t, n, x; 77 scanf("%d", &t); 78 for(int item = 1; item <= t; item++) 79 { 80 scanf("%d", &n); 81 build(1, n, 1); 82 for(int i = 1; i <= n; i++) 83 { 84 scanf("%d", &x); 85 insert(i, x, 1); 86 } 87 char cmd[20]; 88 int a, b; 89 printf("Case %d:\n", item); 90 while(scanf("%s", cmd) != EOF && cmd[0] != 'E') 91 { 92 scanf("%d %d", &a, &b); 93 if(cmd[0] == 'Q') 94 { 95 printf("%d\n", query(a, b, 1)); 96 } 97 else if(cmd[0] == 'A') 98 { 99 insert(a, b, 1); 100 } 101 else if(cmd[0] == 'S') 102 { 103 insert(a, -b, 1); 104 } 105 } 106 } 107 return 0; 108 }