HDU1542矩形領域の走査セグメントツリーと

トピックへのリンク: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; 
            更新(11、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 
}

 

おすすめ

転載: www.cnblogs.com/qingjiuling/p/11330889.html