敌兵布阵 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 }