Uva11992-Fast Matrix Operations (line segment tree + interval modification + good questions)
This is an example in the big white book, which has never been dropped by A. This is a good question for modifying the line segment tree.
Three fields, Max, Min, sum, that is, the maximum value, minimum value, interval, and
Question:
The entire 0 matrix of column C in the r row. Three operations are supported: 1x1 Y1 X2 Y2 v sub-matrix (x1, Y1, X2, Y2) add all elements of the V2 X1 Y1 X2 Y2 v sub-matrix (x1, Y1, X2, Y2) to the V3 X1 Y1 X2 Y2 query sub-matrix (x1, Y1, X2, the data range of Max, sum, and min in Y2 is 0 <C <= 20 1 <m <= 20000
Analysis:
We can see that the row R of the matrix is no more than 20. The idea in the White Book is to create a line segment tree for each line, so that it becomes a one-dimensional line segment tree. 3x1 Y1 X2 Y2: Query () is performed on rows x1-X2, sum is added, and Max and min are compared. It is worth mentioning that there are two modification operations in this question, one is add, and the other is set. Here, two additional settings are maintained: setv and addv. And they are sequential. You can think about it. No matter how many items are after the set, the values after the set are changed to the values after the set. Therefore, it is not necessary to mark such items by adding and then directly clear them. 1: When there are two tags, first process set and then process Add2: The set operation understands the addv tag, but the add operation does not know the setv operation. For details, refer to the code.
/*************************************** * ******** ID: whiteblock63lang: G ++ prog: Uva11992-Fast matrix operationdate: 10:34:04 ************************************** * **********/# include <cstdio> # include <cstring> # include <iostream> # include <algorithm> using namespace STD; # define CLR (a, B) memset (a, B, sizeof (A) # define ls o <1 # define Rs o <1 | 1 # define RT l, r, O # define lson L, M, O <1 # define rson m + 1, R, O <1 | 1 const int node_size = 1 <17; const int INF = 0x3f3f3f; int op, x1, x2, Y1, Y2, X, V;
// Input the inline void scan (Int & X) {char C; while (C = getchar (), C <'0' | C> '9 '); X = C-'0'; while (C = getchar (), c> = '0' & C <= '9 ') X = x * 10 + C-'0 ';}
// Struct segtree {int sumv [node_size], MINV [node_size], maxv [node_size]; int setv [node_size], addv [node_size]; void pushup (INT l, int R, int o) {If (L <r) {sumv [O] = sumv [ls] + sumv [RS]; MINV [O] = min (MINV [ls], MINV [RS]); maxv [O] = max (maxv [ls], maxv [RS]);} if (setv [O]> = 0) {MINV [O] = maxv [O] = setv [O]; sumv [O] = setv [O] * (R-l + 1);} If (addv [O]) {MINV [O] + = addv [O]; maxv [O] + = Addv [O]; sumv [O] + = addv [O] * (R-l + 1) ;}} void Pushdown (int o) {If (setv [O]> = 0) {setv [ls] = setv [RS] = setv [O]; addv [ls] = addv [RS] = 0; setv [O] =-1; // clear mark} If (addv [O]) {addv [ls] + = addv [O]; addv [RS] + = addv [O]; addv [O] = 0; // clear flag} void Update (int l, int R, int o) {If (Y1 <= L & R <= Y2) {If (OP = 1) addv [O] + = V; else setv [O] = V, addv [O] = 0;} else {Pushdown (o); In T m = L + r> 1; if (Y1 <= m) Update (lson); else pushup (lson); If (Y2> m) Update (rson ); else pushup (rson);} pushup (RT);} void query (int l, int R, int o, Int & SSUM, Int & Smin, Int & Smax) {pushup (RT); // process the flag if (Y1 <= L & R <= Y2) {SSUM = sumv [O]; smin = MINV [O]; Smax = maxv [O];} else {Pushdown (o); int M = L + r> 1; int lsum = 0, lmin = inf, Lmax =-INF; int rs Um = 0, rmin = inf, rmax =-INF; If (Y1 <= m) query (lson, lsum, Lmin, Lmax); else pushup (lson ); if (Y2> m) query (rson, rsum, rmin, rmax); else pushup (rson); SSUM = lsum + rsum; Smin = min (Lmin, rmin ); smax = max (Lmax, rmax) ;}}; const int maxr = 20 + 5; segtree [maxr]; int main () {int R, C, M; while (~ Scanf ("% d", & R, & C, & M) {CLR (tree, 0); For (x = 1; x <= R; ++ X) {CLR (tree [X]. setv,-1); tree [X]. setv [1] = 0;} while (M --) {scan (OP); scan (X1); scan (Y1); scan (X2); scan (Y2 ); if (OP <3) {scan (V); For (x = x1; x <= x2; ++ X) tree [X]. update (1, C, 1) ;}else {int gsum = 0, gmin = inf, gmax =-INF; For (x = x1; x <= x2; ++ X) {int SSUM, Smin, Smax; tree [X]. query (1, C, 1, SSUM, Smin, Smax); gsum + = SSUM; gmin = min (gmin, Smin); gmax = max (gmax, Smax );} printf ("% d \ n", gsum, gmin, gmax) ;}} return 0 ;}
Uva11992-Fast Matrix Operations (line segment tree + interval modification + good questions)