Hdu_3340
It is easy to think of using a line segment tree to query the area and sum within a range. However, the key problem is that a polygon is added, so how can we change the area and number of a range by the mark?
Because Tag superposition is involved in the process of downloading tags, we should try to convert the increment of the area into a form that can be stacked for calculation.
When calculating the geometric area, there is one way to convert it into a step-wise cumulative calculation of the directed area, and the area of the trapezoid mainly depends on the two bottom and the length of the height. For this question, the length of the trapezoid height is the length of the upper range of the X axis, which is easily obtained, and the length of the two ends is exactly the mark that we want to overlay, because (a + B) * H/2 + (C + D) * H/2 = (A + C) + (B + D) * H/2, based on the length of the two ends, you can calculate the directed area value of the trapezoid that is added in the same interval. You can also calculate the mark that needs to be transferred to the left and right sons.
Think of this, the idea of this question is there. Since the coordinate value span is large, we can read and save all the problems first, and then discretization X. Volume [] is used to represent the area and the range. At the same time, two tags are required: DL [] (the variation of the Left Bottom of the trapezoid) and Dr [] (the variation of the Right Bottom of the trapezoid ), you can also use a flag [] to indicate whether the interval has been modified. When downloading the change volume at the left and right bottom, you need to calculate the change of DL [] and Dr [] in the left and right Subtrees in proportion, which makes it easy to understand.
# Include <stdio. h> # Include < String . H> # Include <Stdlib. h> # Define Maxd 125010 Double DL [ 4 * Maxd], Dr [ 4 * Maxd], volume [ 4 * Maxd]; Int N, TX [maxd], X, flag [ 4 * Maxd]; Struct Question { Char B [ 5 ]; Int N, x [ 10 ], Y [ 10 ];} Question [maxd]; Int Cmpint ( Const Void * _ P, Const Void * _ Q ){ Int * P = ( Int *) _ P, * q = ( Int * ) _ Q; Return * P <* Q? - 1 : 1 ;} Void Build ( Int Cur, Int X, Int Y ){ Int Mid = (x + y)>1 , Ls = cur < 1 , RS = (cur < 1 ) | 1 ; Dl [cur] = Dr [cur] = Volume [cur] = Flag [cur] = 0 ; If (X = Y) Return ; Build (LS, X, mid); Build (RS, mid + 1 , Y );} Void Init (){ Int I, j, k, n; scanf ( " % D " ,& N); k = 0 ; For (I = 0 ; I <n; I ++ ) {Scanf ( " % S " , Question [I]. B ); If (Question [I]. B [ 0 ] = ' Q ' ) {Scanf ( " % D " , & Question [I]. X [ 0 ], & Question [I]. Y [ 0 ]); TX [K ++] = Question [I]. X [ 0 ], TX [k ++] = question [I]. Y [ 0 ];} Else {Scanf ( " % D " ,& N); question [I]. n = N; For (J = 0 ; J <n; j ++ ) {Scanf ( " % D " , & Question [I]. X [J], & Question [I]. Y [J]); TX [K ++] = Question [I]. X [J];} question [I]. X [N] = Question [I]. X [ 0 ], Question [I]. Y [N] = question [I]. Y [ 0 ] ;}} Qsort (TX, K, Sizeof (TX [ 0 ]), Cmpint); x =- 1 ; For (I =0 ; I <K; I ++ ) If (I = 0 | TX [I]! = TX [I- 1 ]) TX [ ++ X] = TX [I]; build ( 1 , 0 , X- 1 );} Int BS ( Int X ){ Int Mid, min = 0 , Max = x + 1 ; For (;) {Mid = (Min + max)> 1 ; If (Mid = Min) Break ; If (TX [Mid] <= X) min =Mid; Else Max = Mid ;} Return Mid ;} Double Calculate ( Double X1, Double Y1, Double X2, Double Y2, Double X ){ Return (X2-x) * Y1 + (X-X1) * Y2)/(x2-X1 );} Void Pushdown ( Int Cur, Int X, Int Y ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = (cur < 1 ) | 1 ; If (Flag [cur]) {flag [ls] = Flag [RS] = 1 ; Double Delta = calculate (TX [X], DL [cur], TX [Y + 1 ], Dr [cur], TX [Mid + 1 ]); Dl [ls] + = DL [cur], Dr [ls] + = delta, volume [ls] + = (DL [cur] + delta) * (TX [Mid + 1 ]-TX [x])/ 2 ; Dl [RS] + = Delta, Dr [RS] + = Dr [cur], volume [RS] + = (delta + Dr [cur]) * (TX [Y + 1 ]-TX [Mid + 1 ])/2 ; Dl [cur] = Dr [cur] = Flag [cur] = 0 ;}} Void Update ( Int Cur) {VOLUME [cur] = Volume [cur < 1 ] + Volume [(cur < 1 ) | 1 ];} Double Query ( Int Cur, Int X, Int Y, Int S, Int T ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = (cur < 1 ) | 1 ; If (X> = S & Y <= T) Return Volume [cur]; Pushdown (cur, x, y ); If (Mid> = T) Return Query (LS, X, mid, S, T ); Else If (Mid + 1 <= S) Return Query (RS, Mid + 1 , Y, S, T ); Else Return Query (LS, X, mid, s, t) + query (RS, Mid + 1 , Y, S, T );} Void Refresh ( Int Cur, Int X, Int Y, Int S, Int T, Double YS, Double Yt ){ Int Mid = (x + y)> 1 , Ls = cur <1 , RS = (cur < 1 ) | 1 ; If (X> = S & Y <= T) {flag [cur] = 1 ; Double Dleft, dright; dleft = Calculate (TX [s], ys, TX [T + 1 ], Yt, TX [x]); dright = Calculate (TX [s], ys, TX [T + 1 ], Yt, TX [Y + 1 ]); Dl [cur] + = Dleft, Dr [cur] + = dright, volume [cur] + = (dleft + dright) * (TX [Y + 1 ]-TX [x])/ 2 ; Return ;} Pushdown (cur, x, y ); If (Mid> = S) Refresh (LS, X, mid, S, T, ys, yt ); If (Mid + 1 <= T) Refresh (RS, mid +1 , Y, S, T, ys, yt); Update (cur );} Void Solve (){ Int I, J, K, E, X1, Y1, X2, Y2; For (I = 0 ; I <n; I ++ ){ If (Question [I]. B [ 0 ] = ' Q ' ) {J = BS (question [I]. X [ 0 ]), K = BS (question [I]. Y [ 0 ]); If (J < K) printf ( " %. 3f \ n " , Query ( 1 , 0 , X- 1 , J, k- 1 )); Else Printf ( " 0.000 \ n " );} Else { For (E = 0 ; E <question [I]. N; e ++ ) {J = BS (question [I]. X [e]), k = BS (question [I]. X [e + 1 ]); If (J <K) Refresh ( 1 , 0 , X- 1 , J, k- 1 ,-Question [I]. Y [e],-question [I]. Y [e + 1 ]); Else If (J> K) Refresh ( 1 , 0 , X- 1 , K, J-1 , Question [I]. Y [e + 1 ], Question [I]. Y [e]) ;}}} Int Main (){ Int T; scanf ( " % D " ,& T ); While (T -- ) {Init (); solve ();} Return 0 ;}