Uva_11192
If these operations are performed on a one-dimensional sequence, then the line segment tree can be used. But now the question expands these operations to two-dimensional, recalling that the essence of the Line Segment tree is a binary line segment, then for a two-dimensional matrix, expansion should be a quartile matrix.
# Include <stdio. h> # Include < String . H> # Include <Algorithm> # Define Maxd 1000010 # Define INF 0x3f3f3f Int N, M, P, node; Struct Segtree { Int X1, Y1, X2, Y2, sum, Min, Max, add, to, son [ 4 ], Area; Void Pushdown (); Void Update (); Void Init () {sum = Add = To = 0 ; Son [ 0 ] = Son [ 1 ] = Son [ 2 ] = Son [ 3 ] = 0 ; Min = Inf, max =- INF ;}} st [ 4 * Maxd]; inline Void To ( Int Cur, Int V ){ If (Cur) {st [cur]. = V, St [cur]. Add = 0 ; ST [cur]. Min = ST [cur]. max = V, St [cur]. Sum = V *St [cur]. area;} inline Void Add ( Int Cur, Int V ){ If (Cur) {st [cur]. Add + = V; ST [cur]. Min + = V, St [cur]. MAX + = V, St [cur]. Sum + = V * St [cur]. area;} inline Void Segtree: Pushdown (){ If (){ For ( Int I = 0 ; I < 4 ; I ++ ) To (son [I], to); = 0 ;} If (ADD ){ For ( Int I = 0 ; I < 4 ; I ++ ) Add (son [I], add); add = 0 ;} Inline Void Segtree: Update () {min = Inf, max =-INF, sum = 0 ; For ( Int I = 0 ; I < 4 ; I ++ ) {Sum + = St [son [I]. sum; min = STD: min (Min, St [son [I]. min); max = STD: max (max, St [son [I]. max );}} Void Build ( Int Cur, Int X1, Int X2, Int Y1, Int Y2 ){ Int Midx = X1 + x2> 1 , Midy = Y1 + y2> 1 ; ST [cur]. INIT (), St [cur]. Sum = ST [cur]. min = sT [cur]. max =0 ; ST [cur]. X1 = X1, St [cur]. x2 = x2, St [cur]. y1 = Y1, St [cur]. y2 = Y2, St [cur]. area = (x2-X1 + 1 ) * (Y2-Y1 + 1 ); If (X1 = X2 & Y1 = Y2) Return ; ST [cur]. Son [ 0 ] = ++ Node, build (node, X1, midx, Y1, midy ); If (Midx < X2) ST [cur]. Son [ 1 ] = ++ Node, build (node, midx + 1 , X2, Y1, midy ); If (Midx <X2 & midy < Y2) ST [cur]. Son [ 2 ] = ++ Node, build (node, midx + 1 , X2, midy + 1 , Y2 ); If (Midy < Y2) ST [cur]. Son [ 3 ] = ++ Node, build (node, X1, midx, midy +1 , Y2); ST [cur]. Update ();} Void Init () {st [ 0 ]. INIT (), node = 1 ; Build ( 1 , 1 , N, 1 , M);} inline Int Inside ( Int K, Int X1, Int X2, Int Y1, Int Y2 ){ Return St [K]. x1> = x1 & St [K]. x2 <= X2 & St [K]. y1> = Y1 & St [K]. y2 <= Y2;} inline Int Inter ( Int K, Int X1, Int X2, Int Y1, Int Y2 ){ If (St [K]. X2 <X1 | st [K]. x1> X2 | st [K]. Y2 <Y1 | st [K]. Y1> Y2) Return 0 ; Return 1 ;} Void Refresh ( Int Cur, Int X1, Int X2, Int Y1, Int Y2, Int V, Int OP ){ If (Inside (cur, x1, x2, Y1, Y2 )){ If (OP = 1 ) Add (cur, V ); Else To (cur, V ); Return ;} St [cur]. Pushdown (); For ( Int I = 0 ; I < 4 ; I ++) If (St [cur]. Son [I] & Inter (ST [cur]. son [I], x1, x2, Y1, Y2) Refresh (ST [cur]. son [I], x1, x2, Y1, Y2, V, OP); ST [cur]. update ();} Void Query ( Int Cur, Int X1, Int X2, Int Y1, Int Y2, Int & Sum, Int & Min, Int & Max ){ If (Inside (cur, x1, x2, Y1, Y2) {sum + = ST [cur]. Sum, min = STD: min (Min, St [cur]. min), max = STD: max (max, St [cur]. max ); Return ;} St [cur]. Pushdown (); For ( Int I = 0 ; I < 4 ; I ++ ) If (St [cur]. Son [I] &Inter (ST [cur]. son [I], x1, x2, Y1, Y2) query (ST [cur]. son [I], x1, x2, Y1, Y2, sum, Min, max );} Void Solve (){ Int I, op, X1, Y1, X2, Y2, V, Min, Max, sum; For (I = 0 ; I <p; I ++ ) {Scanf ( " % D " , & OP, & X1, & Y1, & X2 ,& Y2 ); If (OP = 3 ) {Min = Inf, max =-INF, sum = 0 ; Query ( 1 , X1, x2, Y1, Y2, sum, Min, max); printf ( " % D \ n " , Sum, Min, max );} Else {Scanf ( " % D " ,& V); refresh ( 1 , X1, x2, Y1, Y2, V, OP );}}} Int Main (){ While (Scanf ( " % D " , & N, & M, & P) = 3 ) {Init (); solve ();} Return 0 ;}