2019 꽉 전기 멀티 학교 눈 스마일 hdu6638 (가장 하위 세그먼트와 세그먼트 트리)

질문의 의미 : 어떤 시점에서 산란, 양과 음의 값, 직사각형 상자가되도록 사각형의 최대 값의 합

해결책 : 제 이산 y는, 다른 열거 각각 X 좌표를 경계로, 삽입 지점 이후 정렬 순서를 X, 열거의 하부 경계는 최대 세그먼트 트리 서브 세그먼트를 갱신

사용법 #include <iostream> 
#INCLUDE <cstdio> 
#INCLUDE <cstdlib> 
#INCLUDE <CString을> 
#INCLUDE <알고리즘> 
#INCLUDE <cmath> 
#INCLUDE <큐> 
#INCLUDE <일람> 
#INCLUDE <math.h> 
#INCLUDE < 벡터> 
#INCLUDE <적층> 
#INCLUDE < 문자열 > 
#INCLUDE <STDIO.H> 사용 스페이스 성병; 
타입 정의 LL;
CONST의 INT MAXN = 2e3 + (10) ;

   

 (10) ; 

구조체 T { 
    LL의 X, Y, w; 
    T () {} 
    T (LL의 X, Y의 LL, LL의 w) : X (X), Y (Y)} {(w) w 
} A [MAXN]; 

구조체 Segtree {
     INT의 L, R; 
    LL LX, RX, MX, 합; 
일} [MAXN << 2 ]; 

부울 CMP (T를 A, T의 b) 
{ 
    복귀 AX < BX; 
} 
LL의 B [MAXN]; 

보이드 팔 굽혀 펴기 ( INT O) 
{ 
    세인트 [0] .sum = 세인트 [0 << 1 ] + .sum 세인트 [0 << 1 | 1 ] .sum; 
    세인트 [0] .lx = 최대 (세인트 [0 << 1] .lx 세인트 [0 << 1 ] + .sum 세인트 [0 << 1 | 1 ] .lx); 
    세인트 [0] .rx = 최대 (세인트 [0 << 1 | 1 ] .rx 세인트 [0 << 1 | 1 ] + .sum 세인트 [0 << 1 ] .rx); 
    세인트 [0] .mx = 최대 (최대 (세인트 [O << 1 .mx, 세인트 [0 << 1 | 1 ] .mx), 세인트 [0 << 1 ] + .rx 세인트 [0 << 1 | 1 ] .lx); 
} 
공극 빌드 ( INT의 O, INT의 L, INT의 R) 
{ 
    세인트 [0] 펜닐 = 1; 세인트 [0] = .R아르 자형; 
    세인트 [0] .sum = 세인트 [0] = .mx 세인트 [0] = .lx 세인트 [0] .rx = 0 ;
    경우 (L == R)이 
    { 
        리턴 ; 
    } 
    INT m = (L +의 연구) >> 1 ; 
    (O 구축 << 1 , L, m); 
    빌드 (O << 1 | 1 , m + 1 , R); 
} 
공극 인서트 ( INT의 O, INT의 X, INT w) 
{ 
    경우 (세인트 [0] == .L 세인트 [0] .R) 
    { 
        세인트 [0] .sum세인트 = [0] 일 .lx = [0] 일 .rx = [0] 일 .mx = [0] .mx + w;
        반환 ; 
    } 
    INT m = (세인트 [0] + .L 세인트 [0] .R) >> 1 ;
    경우 (X <= m) (오 삽입 << 1 , X, W);
    다른 (O 삽입 << 1 | 1 ], X, w) 
    팔 굽혀 펴기 (O); 
} 
INT 의 main () 
{ 
    INT의 t; 
    scanf와 ( " %의 D " , t);
    반면 (t-- ) 
    { 
        INT의 N; 
        scanf와 ( " %의 D ' , N);
        위한 ( int로 I = 1 ; I ++는, 난 <= N ) 
        { 
            LL의 X, Y, w; 
            scanf와 ( " % LLD % LLD % LLD " , X, Y, W); 
            A [I] = T (X, Y, W); 
            B [I]는 = Y; 
        } 
        정렬 (B + 1 , B +는 N + 1 );
        INT의 K = 고유 (B + 1 , B + N + 1 ) - (B) - 1 ;
        위한 ( int로 난 = 1 난 = <N; I ++는  )
        {
             INT Y = LOWER_BOUND (B + 1 , B + K + 1 , A [I]를 .Y) - B; 
            A [I]는 .Y = Y; 
        } 
        정렬 (a + 1 + N +하는 1 , CMP); 
        LL의 ANS = 0 ;
        위한 ( int로 I = 1 ; i가 N = <; 내가 ++ ) 
        { 
            경우 (I! = 1 && A [I] .x를 == A [I - 1 ] .x를)
                 계속 ; 
            구축 ( 1 , 1 , K);
            대한 ( 의 INT J = 1; J <= N; J ++ ) 
            { 
                경우 ! (j = 1은 [J]를 && .X = A [J - 1 ] .x를) 
                    ANS = 최대 (ANS 세인트 [ 1 ] .mx); 
                (삽입 1 , A [J] .Y하는 [J]를 .W); 
            } 
            ANS = 최대 (ANS 세인트 [ 1 ] .mx); 
        } 
        COUT << ANS << ENDL; 
    } 
}

 

추천

출처www.cnblogs.com/smallhester/p/11319701.html