루오 밸리 2894

사용법 #include <iostream> 
#INCLUDE <cstdio> 

#DEFINE LS (O) O << 1 
#DEFINE RS (O) O << 1 | 1 

사용 스페이스 성병; 

CONST INT의 WX = 50,017을; 

인라인 INT 읽기 () { 
    INT 합 = 0, F = 1; 숯 CH = getchar가 (); 
    동안 (CH2 <0 || CH> '9') {경우 (CH2 == '-') F = -1; CH = getchar가 ();} 
    동안 (CH2> = 0 && CH <=에서 '9') {합계 = SUM (<< 1) + (합 << 3) + CH-'0 '; CH = getchar가 ();} 
    환원 액 * F; 
}은 

N INT, m; 

구조체 SGT { 
    INT의 L, R, 태그 lsum, rsum, 합; 
    #DEFINE 태그 (O) t [0] .tag 
    #DEFINE lsum (O) t [0] .lsum 
    #DEFINE rsum (O) t [0] .rsum 
    #DEFINE 합 (O) t [0] .sum 
} t [WX * 4;

    경우 (SUM (LS (O)) == t [LS (O)]. RT [LS (O)]. L + 1) lsum (O) = SUM (LS (O)) + lsum (RS (O) ); 
    다른 lsum (O) = lsum (LS (O)); 
    경우 (SUM (RS (O)) == t [RS (O)]. RT [RS (O)]. L + 1) rsum (O) = SUM (RS (O)) + rsum (LS (O) ); 
    다른 rsum (O) = rsum (RS (O)); 
    합 (O) = 최대 (최대 (SUM (LS (O)), 합 (RS (O))) rsum (LS (O)) + lsum (RS (O))); 
} 

보이드 다운 INT (O) { 
    경우 (태그 (O) == 0) { 
        SUM (LS (O)) = lsum (LS (O)) = rsum (LS (O)) = t [LS (O)] . .rt [LS (O)] L + 1; 
        .. 합 (RS (O)) = lsum (RS (O)) = rsum (RS (O))에서 t = [RS (O)]을 실온 [RS (O)] L + 1; 
        태그 (LS (O)) = 태그 (RS (O)) = 태그 (O); 
        태그 (O) = - 1; 
    } 
    경우 (태그 (O) == 1) { 
        SUM (LS (O)) = lsum (LS (O)) = rsum (LS (O)) = 0; 
        합계 (RS (O)) = lsum (RS (O)) = rsum (RS (O)) = 0;
        태그 (LS (O)) = 태그 (RS (O)) = 태그 (O); 
        태그 (O) = - 1; 
    } 
} 

공극 빌드 (INT 오, INT의 L, R의 INT)을 { 
    t [0] = L .L 단계; t [0] = R .R; 태그 (O) = - 1; 
    경우 (L == R)의 합 {(O) = lsum (O) = rsum (O) = 1; 반환} 
    미드의 t = [0] 펜닐 + t [0] int로 .R >> 1; 
    (L <= MID) 빌드 (LS (O) L, MID)의 경우; 
    경우 (R> MID) 빌드 (RS (O), 미드 + 1, R); 
    최대 (O); 
} 

공극 업데이트 (INT 오, INT의 L, INT의 R, INT의 k)를 { 
    경우 (L <= t [0] 펜닐 && t [0] .R <= R) { 
        경우 (! K) { 
            합 (O) = lsum (O) = rsum (O) = t의 [0] .rt [0] 펜닐 + 1; 
            태그 (O) = K; 
        } 
        다른 { 
            합 (O) = lsum (O) = rsum (O) = 0; 
            태그 (O) = K; 
        }
        반환; 
    } 
    아래 (O); 
    INT의 중간 = t [0] + .L를 t [0] .R >> 1; 
    경우 (L <= MID) 업데이트 (LS (O), L, R, K); 
    (R> MID) 업데이트 (RS (O)의 경우, L, R,
    최대 (O); 
} 

INT 쿼리 (INT O, INT의 L, R의 INT, INT LEN) { 
    경우 (L == R) 복귀 L; 
    다운 (O); 
    경우. (t [LS (O)] 합계> = LEN) 리턴 질의 (LS (O), L, R, LEN); 
    다른 경우 (t [LS (O)] rsum + t [RS (O)] lsum> = LEN..) 반환 t [LS (O), R-rsum (LS (O)) + 1.; 
    그렇지 않은 경우 쿼리 (RS (O), L, R, 렌); 
} 

{) INT (주 
    ) (N = 판독; m = 판독 (); (1,1, N)를 작성; 
    {위해 (; I <= m ++ 나 I = 1 INT) 
        INT 선택 해제하는 단계; 
        ) (= 판독 해제; 
        경우 (최적화 == 1) { 
            INT (X); 
            X = 판독 (); 
            경우 (SUM (1) <X) { 
                둔다 ( "0");
                계속하다; 
            } 
            INT의 쿼리 TMP = (1,1, N, X); 
            의 printf ( "% D \ 없음"TMP); 
            업데이트 (1, TMP, TMP + X-1,1); 
        } 
        다른 { 
            INT의 X, Y; 
            X = 판독 (); Y는 판독 = (); 
            업데이트 (1, X, X + Y-1,0); 
        } 
    } 
    0을 리턴; 
}

  인터넷에서 코드의 복사,하지만 불행히도, 즉, 나는이 세그먼트의 나무에 익숙하지 않았다가, 단지 세 개의 숫자가 실제로 오래 오래, 오른쪽 공간의 중간의 전체 길이 왼쪽 공간에서, 유지, 나는 충분히 생각 그래서 쓰기 분명이 바로 정상입니다

추천

출처www.cnblogs.com/coolwx/p/11639110.html