Title: Enemy Lineup
Standard segment Tree Template code:
#include <cstdio> #include <cstring>const int maxn = 500000 + 10;struct node{int left, right, count;} Node[maxn];int a[maxn];/************************************************** Achievement ****************************i is the interval serial number * L is the left boundary of interval I. R is the interval I right boundary * * * from 1 to N to build, until the interval length of 1*** is L=r, the end. Count record interval and **************************************/void maketree (int l, int r, int i) {node[i].left = l; Node[i].right = R; if (L = = r) {node[i].count = a[l]; return; } int m = (L + r)/2; Maketree (L, M, 2*i); Maketree (M + 1, R, 2*i + 1); Node[i].count = node[2*i].count + Node[2*i + 1].count;} /********************************************************* update ********************i interval sequence number. X the point to update.Y the value to update **********flag inference update mode *****************************************************/void updatetree (int i, int x, int y, int flag) {int L = node[i].left; int r = node[i].right; int m = (L + r)/2; if (r = = L) {if (flag) Node[i].count + = y; else node[i].count-= y; Return } if (x <= m) updatetree (2*i, x, y, flag); else Updatetree (2*i + 1, x, y, flag); if (flag) Node[i].count + = y; else node[i].count-= y; return;} /************************************************** Query ****************************************************/int Querytree (int l, int r, int i) {int m = (node[i].left + node[i].right)/2; if (node[i].right <= r && node[i].left >= L) return node[i].count; int ans = 0; if (r <= m) return Querytree (L, R, 2*i); else if (L > m) return Querytree (L, R, 2*i + 1); else return Querytree (L, M, 2*i) + querytree (M + 1, R, 2*i + 1);} int main () {int T, n; Char str[20]; scanf ("%d", &t); for (int i = 1; I <= T; i++) {printf ("Case%d:\n", i); scanf ("%d", &n); for (int i = 1; I <= n; i++) scanf ("%d", &a[i]); Maketree (1, N, 1); int x, y; while (scanf ("%s", str)) {if (str[0] = = ' E ') break; scanf ("%d%d", &x, &y); if (str[0] = = ' Q ') printf ("%d\n", Querytree (x, Y, 1)); else if (str[0] = = ' A ') updatetree (1, x, y, True); else Updatetree (1, x, y, false); }} return 0;}
Graceful line-segment tree code:
#include <cstdio>/***************************** flexible use of macro definitions ******************************/#define Lson L, M, RT << 1#define Rson m + 1, R, RT << 1 | 1const int maxn = 55555;int sum[maxn<<2];void pushup (int rt) {Sum[rt] = sum[rt<<1] + sum[rt<<1|1];} /*************************************************** *************** The structure is not used here, only the interval and sum are recorded, but the l,r is closely associated with the interval ordinal. /void Build (int l,int R,int RT) {if (L = = r) {scanf ("%d", &sum[rt]); return;} int m = (L + R) >> 1;build (Lson); build (Rson); Pushup (RT);} /*************************************** ***************** Update ***************** here does not use Tag Update mode (plus or minus). Cleverly handled the sign at call, reduced function Reference ***************************************/void Update (int p,int add,int l,int r,int RT) {if (L = = r) {s UM[RT] + = Add;return;} int m = (L + R) >> 1;if (P <= m) update (p, add, Lson); Else Update (p, add, Rson); Pushup (RT);} /********************************************************* Query ****************** subtly references a variableRET, reduced the discussion of M ***************************************/int query (int l,int r,int l,int r,int RT) {if (L <= l && R <= R) {return sum[rt];} int m = (L + R) >> 1;int ret = 0;if (l <= m) ret + = query (l, R, Lson), if (R > m) ret + = query (l, R, Rson); return ret;} int main () {int T, n;scanf ("%d", &t), for (int cas = 1; CAs <= T; cas + +) {printf ("Case%d:\n", CAs); scanf ("%d", &am P;N); Build (1, N, 1), Char op[10];while (scanf ("%s", op)) {if (op[0] = = ' E ') Break;int A, b;scanf ("%d%d", &a,&b); if (op[0] = = ' Q ') printf ("%d\n", query (A, B, 1, N, 1)), else if (op[0] = = ' S ') update (A,-B, 1, n, 1); Else update (A, b, 1, n, 1);}} return 0;}
The same is true of the two code ideas. Only the code style is different, the execution time. Memory is still the same. This topic only involves single-point updates and interval sums. So it can be solved with a tree-like array, the code is more concise, and the execution speed is faster.
But the tree-like array can find the interval and cannot find the interval maximum, and the general solution is still solved by the segment tree.
The code for the tree-like array:
#include <cstdio> #include <cstring>using namespace Std;const int maxn = 50000 + 10;int len, A[maxn];char str[50 ];int lowbit (int x) {return x& (-X);} /****************************** Update ********************************/void Update (int i, int v) {while (I <= Len) { A[i] + = V; i + = Lowbit (i); }}/***************************** sum ******************************/int sum (int i) {int sum = 0; while (i > 0) {sum + = A[i]; I-= lowbit (i); } return sum;} int main () {int T, V; scanf ("%d", &t); for (int i = 1; I <= T; i++) {memset (A, 0, sizeof (a)); scanf ("%d", &len); for (int j = 1; j <= Len; j + +) {scanf ("%d", &v); Update (J, v); } printf ("Case%d:\n", i); while (scanf ("%s", str)) {if (str[0] = = ' E ') break; int x, y; scanf ("%d%d", &x, &y); if (str[0] = = ' A ') update (x, y); else if (str[0] = = ' S ') update (x,-y); else printf ("%d\n", sum (y)-sum (x-1)); }} return 0;}
Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.
Chishuki update enemy lineup at a single point