POJ3667 호텔 (세그먼트 트리)

이 질문은 머리와 poj1823과 동일

나는 또 다른 과제 해결을 참조 할 수 있습니다

유일한 차이점은 그가 가장 왼쪽 찾고 있는지, 우리가 더 자연스럽게 더 왼쪽을 고려할 수있다

현재 L 최대 포인트는 직접 다시 충족하는 경우

그렇지 않으면, 왼쪽 노드에 현재 포인트 티맥스 대회의 왼쪽 아들을 가면

그것은 만약 범위에 걸쳐뿐만 아니라 직접 반환

권리 아들 경우, 그의 아들은 오른쪽으로 갔다

이미 선고 된 특별하지 않을 경우, 그래서 한 번 입력, 그것이 충족해야합니다.

사용법 #include <iostream> 
#INCLUDE <큐> 
#INCLUDE <지도> 
#INCLUDE <벡터> 
#INCLUDE <cstdio> 
#INCLUDE <알고리즘> 
#INCLUDE <적층>
 사용  공간이 수 std;
형식 정의를 오래  오래 LL;
CONST  INT N = + 1E6 (10) ;
CONST  INT INF = 0x3f3f3f3f ;
구조체 노드 {
     INT의 L, R;
    int로 게으른;
    INT 티맥스;
    INT L 최대;
    INT의 Rmax가;
} P [N];
보이드 팔 굽혀 펴기 ( INT U) {
    TR [U] .rmax = TR [U << 1 | 1 ] .rmax;
    경우 (TR [U << 1 | 1 ] .lazy == - 1 )
        TR [U] .rmax + = TR [U << 1 ] .rmax;
    TR [U] .lmax = TR [U << 1 ] .lmax;
    경우 (TR [U << 1 ] .lazy == - 1 )
        TR [U] .lmax + = TR [U << 1 | 1 ] .lmax;
    TR [U] .tmax = 최대 (TR [U << 1 ] .rmax + TR [U << 1 | 1 ] .lmax 맥스 (TR [U << 1 ] .tmax, TR [U << 1 | 1 ] .tmax));
    경우 (TR [U << 1 ] == .lazy TR [U << 1 | 1 ] .lazy)
        TR [U] .lazy = TR [U << 1 ] .lazy;
    다른 {
        P [U] .lazy = 0 ;
    }
}
보이드 빌드 ( INT U, INT (L), INT (R)) {
     경우 (L == R) {
        TR [U] = (노드) {L, L - 1 , 1 , 1 , 1 };
    }
    다른 {
        TR [U] = (노드) {L, R, - 1 };
        INT 중간 = L + R >> 1 ;
        빌드 (U << 1 , L, MID);
        빌드 (U << 1 | 1 중간 + 1 , R);
        (U)를 팔 굽혀 펴기;
    }
}
보이드 푸시 ( INT U) {
    TR [U << 1 ] .lazy = TR [U << 1 | 1 ] .lazy = TR [U] .lazy;
    경우 (TR [U] .lazy == 1 ) {
        TR [U << 1 ] .lmax = TR [U << 1 ] .rmax = TR [U << 1 ] .tmax = 0 ;
        TR [U << 1 | 1 ] .lmax = TR [U << 1 | 1 ] .rmax = TR [U << 1 | 1 ] .tmax = 0 ;
    }
    다른 {
        TR [U << 1 ] .lmax = TR [U << 1 ] .rmax = TR [U << 1 ] .tmax TR = [u는 << 1 ] .R-TR [U << 1 ] 펜닐 + 1 ;
        TR [U << 1 | 1 ] .lmax = TR [U << 1 | 1 ] .rmax = TR [U << 1 | 1 ] .tmax = TR [U << 1 | 1 ] .R-TR [U << 1 | 1 ] 펜닐 + 1 ;
    }
    P [U] .lazy = 0 ;
}
보이드 수정 ( INT U, INT (L), INT (R), INT (X)) {
     경우 (TR [U] 펜닐> = 1 && TR [U] .R <= R) {
        TR [U] .lazy = X;
        경우 (X == 1 ) {
            TR [U] .lmax = TR [U] .rmax = TR [U] .tmax = 0 ;
        }
        다른 {
            TR [U] .lmax = TR [U] .rmax = TR [U] .tmax = TR [U] .R-TR [U] 펜닐 + 1 ;
        }
        반환 ;
    }
    경우 (TR [U] .lazy! = 0 )
        푸시 (U);
    INT 중간 TR = [U] 펜닐 + TR [U] .R >> 1 ;
    경우 (L <= MID)
        수정 (U << 1 , L, R, X);
    경우 (R> 중간) {
        수정 (U << 1 | 1 , L, R, X);
    }
    (U)를 팔 굽혀 펴기;
}
INT 쿼리 ( INT U, INT K) {
     경우 (TR [U] .lmax> = K)
         복귀 TR [U] 펜닐]
    경우 (TR [U << 1 ] .tmax> = K)
         리턴 질의 (U << 1 , K);
    경우 (TR [U << 1 ] .rmax + TR [U << 1 | 1 ] .lmax> = K)
         복귀 TR [U << 1 ] .R-TR [U << 1 ] .rmax + 1 ;
    리턴 질의 (U << 1 | 1 , K);
}
int로 주 () {
     INT의 N, m을;
    CIN >> >> N m;
    빌드 ( 1 , 1 , N);
    int로 난을;
    위한 은 (i = 1 ; i가 <= m; I ++ ) {
         INT C;
        scanf와 ( " %의 D " , 및 C);
        경우 (c == 1 ) {
             INT의 K;
            scanf와 ( " %의 D ' , K);
            경우 (TR [ 1 ] .tmax < K) {
                의 printf ( " 0 \ n " );
                계속 ;
            }
            INT TMP = 쿼리 ( 1 , K);
            의 printf ( " 가 % d \ n " , TMP);
            수정 ( 1 , TMP, TMP + K- 1 , 1 );
        }
        {
             INT의 L, R;
            scanf와 ( " % D % D ' , L, R);
            수정 ( 1 , L, L + R- 1 - 1 );
        }
    }

}
코드보기

 

추천

출처www.cnblogs.com/ctyakwf/p/12442833.html