POJ2777 트리 라인 간격 색칠 문제

 

 

이탈리아 그건 : 길이 L에 나무, T 색상은 O 작업을 제공하기 위해, 각각의 시간 간격은 일부 염료, 또는 쿼리 유형 컬러 섹션으로 선택 될 수 있습니다

생각 : 라인 세그먼트 리프 노드로 표시되는 디지털 컬러 기록 부모 노드 -1 자식 노드가 두 개의 서로 다른 색> 전체 개수의 부호 자식 노드 0이 색에 대응 한 것을 나타낸다.

사용법 #include <iostream> 
#INCLUDE <cstdio> 
#INCLUDE <알고리즘> 
#INCLUDE <CString을> 
#INCLUDE <cmath>
 사용  스페이스 성병; 

CONST의  INT maxn 1E5 + = 10 ;
INT A [maxn];
INT의 L, t, O;
int로 힘을 [ 35 ];
구조체 노트 
{ 
    int입니다 왼쪽, 오른쪽, 합, 게으른;
    무효화 (최대 INT 브로) 
    { 
        합계 = 브로 단계; 
        게으른 = 발; 
    } 
} 트리 [maxn *4 ];
보이드 팔 굽혀 펴기 ( INT의 ID) 
{ 
    경우 (트리 [ID << 1 ] .sum == - 1 개 || 트리 [ID << 1 | 1 ] .sum == - 1 ) 
        트리 [ID] .sum = - 1 ;
    다른  경우 (트리 [ID << 1 ] == .sum 트리 [ID << 1 | 1 ] .sum) 
        트리 [ID] .sum = 트리 [ID << 1 ] .sum;
    다른 
        나무 [ID] .sum = - 1 ; 
} 
공극 푸시 ( INT의 ID) 
{
    경우 (트리 [ID] .lazy) 
    { 
        트리 [ID << 1 ] .up (트리 [ID] .lazy); 
        트리 [ID << 1 | 1 ] .up (트리 [ID] .lazy); 
        트리 [ID] .lazy = 0 ; 
    } 
} 

공극 빌드 ( INT의 ID, INT의 L, INT의 R) 
{ 
    트리 [ID] .left = L 단계; 
    트리 [ID] 됐지 = R;
    경우 (L == R) 
        트리 [ID] .sum = 1 ;
    다른 
    { 
        INT중간 = (L +에서의 R) / 2 ; 
        빌드 (ID << 1 , L, MID); 
        구축 (ID << 1 | 1 , 중반 + 1 , R); 
        팔 굽혀 펴기 (ID); 
    } 
} 
공극 쿼리 ( INT의 ID, INT의 L, INT의 r)을 
{ 
    경우 (트리 [ID] .sum =! - 1 ) 
    { 
        힘 [트리 [ID] .sum] = 1 ;
        반환 ; 
    } 
//     푸시 (ID); 
    INT 중간 = / (트리 [이드] + 트리 [ID] 됐지 .left) 2 ;
    경우 (L <= MID) 조회 (ID << 1 , L, R);
    만약 (ID << (R> MID) 질의 1 | 1 ], L, R) 
} 
공극 업데이트 ( INT의 ID, INT의 L, INT R, INT 브로) 
{ 
    경우 (L <= 트리 [ID]가 .left && 트리 [ID] 됐지 <= R) 
    { 
        트리 [ID] .up (발); 
        반환 ; 
    } 
    푸시 (ID); 
    INT 중간 = / (트리 [이드] + 트리 [ID] 됐지 .left) 2 ;
    경우 (L <= MID) 업데이트 (ID << 1 , L, R, 발);
    경우 (R> MID) 업데이트 (ID << 1| 1 , L, R, 발); 
    팔 굽혀 펴기 (ID); 
} 


INT 의 main () 
{ 
    는 scanf ( " % D % D % D ' , L, t, O); 
    구축 ( 1 , 1 , l);
    위한 ( int로 I = 1 ; i가 <= O 내가 ++ ) 
    { 
        연산하는 단계; 
        getchar가 (); 
        scanf와 ( " %의 C " , OP);
        경우 (OP == ' C ' ) 
        { 
            INT의 L, R, 색상; 
            는 scanf ( "% D % D % D ' , L, R, 및 색), 
            업데이트 ( 1 , L, R, 컬러) 
        } 
        다른 
        { 
            INT의 L, R, 
            는 scanf ( " % d 개 %의 D ' , L, R); 
            memset 함수 (힘, 0 , 는 sizeof (힘)) 
            질의 ( 1 , L, R)
             INT ANS = 0 ;
             위해 ( int로 I = 1 ; i가 = < 30 ; i가 ++ ) 
            { 
                경우 VIS ([I]) 
                    ANS++ ; 
            } 
            의 printf ( " % D \ 없음 " , ANS); 
        } 
    } 
}

 

추천

출처www.cnblogs.com/dongdong25800/p/11620054.html