トピックへのリンク:http://acm.hdu.edu.cn/showproblem.php?pid=1542
問題の意味:n次元座標軸に平面矩形平行な、長方形の面積を算出すると
良いブログの話があります:https://blog.csdn.net/u013480600/article/details/22548393
セグメントツリーによって直接離散を維持するために必要なメンテナンスはない浮動小数点数の束を維持するために、リーフノードです。
我々は、[X [L + 1]、X [L]、セグメントツリーは、各リーフノード(区間[L、L]を制御する)Xを参照していない[L]は座標注意、むしろ間隔をいうべきである。別のセグメントツリーノードで区間[L、R]を制御し、また、範囲[R + 1] X座標にR間隔、すなわちX [L]の範囲にLのX軸間隔を指します。
要するに、範囲のメンテナンス。
#include <iostreamの> する#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#define半ば(L + R)/ 2 使用 名前空間STDを、 typedefの長い 長いLL。 const int型 MAXN = 1000年 + 10 。 ダブルのDAT [ 4 * MAXN]; int型[MAXN]怠惰。 ダブルB [MAXN]。 構造体の縁{ ダブルL、R、H。 int型のCNT; 友人のブール 演算子 <(エッジX、エッジY){ 戻り XH < YH。 } } E [MAXN]。 ボイド押し上げ(int型、int型の L、INT R){ 場合(怠惰[A])DAT [A] = bの[R + 1 ] - B [L]。 他の DAT [A] =ダット[<< 1 ] +ダット[<< 1 | 1 ]。 } ボイド更新(int型、int型の L、INT R、int型の、INT T、INT K){ 場合(S> R || T <L)の リターン; もし(S <= 1 && R <= T){ 怠惰[A] + = K。 押し上げ(L、R)。 返します。 } 場合(S <= MID)更新(<< 1 、L、中間、S、T、K)。 もし(T> MID)更新(<< 1 | 1、中間+ 1 、R、S、T、K)。 押し上げ(L、R)。 } int型のmain(){ int型N; INT T = 0 。 一方、(〜のscanf(" %d個"、&N)){ memsetの(DAT、0、はsizeof (DAT))。 memsetの(遅延、0、はsizeof (遅延))。 memset(B、0、はsizeof (b)参照)。 memsetの(E、0、はsizeof (e)参照)。 もし(N == 0) 戻り 0 ; T ++ ; int型のp = 0、NUM = 0 ; 以下のために(int型私= 1 ; iが<= N; iが++ ){ ダブルX1、X2、Y1、Y2、 scanf関数(" %LF%LF%LF%LF "、&X1、Y1&、&X2、&Y2); E [ ++ P] .L = X1; E [P] .R = X2。 E [P]・H = Y1。 E [P] .CNT = 1 。 E [ ++ P] .L = X1; E [P] .R = X2。 E [P]・H = Y2。 E [P] .CNT = - 1 。 B [ ++ NUM] = X1。 B [ ++ NUM] = X2。 } ソート(E + 1、E + 1つの + P)。 ソート(B +。1、Bの+ 1 + NUM); int型 M = UNIQUE(Bの+ 。1、Bの+ 1 + NUM)-B- 1。; ダブル ANS = 0 ; のための(INT I = 1、私はP <; I ++のを){ int型 L = LOWER_BOUND( + B 1、M + B、E [I] .L) - B; INT R&LT LOWER_BOUND =(Bの+ 1、M + B、E [I] .R) - B; 更新(1、1、M- 1、L 、R- 1、Eは、[I]は.CNT); // 、R-1は、キー部が維持されているM-1の間隔の合計を覚え ANS + = DAT [ 1 ] *(E [I + 1 ] .h- E [I]・H)。 } のprintf(" テストケース#%d個の\ n " 、T)。 printf(" 合計エリアを探検:%.2lf \ n \ n " 、ANS)。 } 戻り 0 。 }