2 가장 긴 부분 배열 학교 다중 세그먼트 트리

  문제의 의미 : N의 C의 K 및 인공 지능 (1-N)의 소정의 시퀀스 번호의 범위 내의 모든 수치는 1-C 모든 요소가 0> = K의 간격으로 표시되도록 긴 구간 길이를 찾아

 

해결 방법 :

우측 단부가 고정되면, 각 요소에 대해, 가능한 좌측 두 개의 연속 점 간격 첨자.
각 요소에 대해, 그 세그먼트 트리 더한 지점의 좌측 범위가 가능하다.
때 가능한 왼쪽 지점 C 요소를 유지하는 권리에 대한 권리 점.
세그먼트 나무는 인덱스를 조회 할 수 있습니다 C의 작은 값을 요청해야합니다.

 

매우 명확 아주 좋은 세그먼트 트리 제목을 생각지도 그리기 

돌봐 값을 기준으로 가장 아래에있는 피사체를 유지하기 위해 

#INCLUDE <비트 / stdc ++ H.>
 사용  스페이스 성병;
// BXD 의해 입력 
#DEFINE의 담당자 (나는 A는 b)에 대한 (; 나는 = (b) <I ++는 i가 (a) = INT)
 #DEFINE에 대한 REPP을 (I, a가, b) (I = (a int로 ) I> = (b) - I)
 #DEFINE RI (N)는 scanf ( "%의 D", 및 (N))
 #DEFINE RII (N, M)는 scanf ( "%의 D % d에", N, 및 m)
 #DEFINE의 RIII (N, M, K)는 scanf ( "% D % D % D", 및 N, M, K)
 #DEFINE의 RS (들)는 scanf ( "%의 S ', S);
#DEFINE 줄게 긴 긴
 #DEFINE의 LSON의 L, m, POS << 1
 #DEFINE의 rson의 m + 1, R, POS << 1 | 1
 #DEFINE PB와 push_back
 #DEFINE REP (I, N)에 대해 (ⅰ = 0을 int로; 난 (N) ";
///////////////////////////////// / 
#DEFINE INF 0x3f3f3f3f
 CONST의  INT N = 1E5 + 5 ;
INT의 t [N << 2 ] 대장균 [N << 2 ] X [N << 2 ];
INT C, K, N, m; 
벡터 < INT > V [N];
무효화 업 ( INT의 POS) 
{ 
    t [POS] = 최대 (t [POS << 1 ], t [POS << 1 | 1 ]); 
    X [POS] = (t [POS] == t [POS << 1 ]) × [POS <<? 1 ], X [POS << 1 | 1 ];
}
 
{무효화 다운 ( INT의 POS) 
{ 
    경우 (COL [POS]) 
    { 
        t [POS << 1 ] + = COL [POS]; 
        t [POS << 1 | 1 ] + = COL [POS]; 
        COL [POS << 1 ] + = COL [POS]; 
        COL [POS << 1 | 1 ] + = COL [POS]; 
        COL [POS는] = 0 ; 
    } 
} 
공극 빌드 ( INT의 L, INT의 R, INT의 POS)를 
    X [POS] 대장균 [POS =; L = 0 ;
    경우 (L == R) {t [POS] = 0 ; 반환 ; }
     INT m = (L + R) >> 1 (rson)을 빌드; (LSON)을 빌드 업 (POS)를; 
} 
공극 upsum ( INT의 L, INT의 R, INT의 V, INT의 L, INT의 R, INT의 POS) 
{ 
    경우 (L> R) ;
    경우 (L <= 1 && R <= R) {COL [pos가] + = V] t [POS] + = V; 반환 ; }
     INT m = (L + R) >> 1 ; 다운 (POS);
    경우 (L <=m) upsum (L, R, V, LSON);
    경우 (R> m) upsum (L, R, V, rson); 
    최대 (POS); 
} 
INT qsum ( INT L, INT의 R, INT의 L, INT의 R, INT의 POS) 
{ 
    경우 (L <= 1 && R <= R) 
    { 
        복귀 t [POS] == C (X) [포스] : 0 ; 
    } 
    INT m = (L + R) >> 1 ; 다운 (POS);
    경우 (L <= m) // 这里一定要注意细节
    {
         INT t = qsum (L, R, LSON);
        만약 (t) 복귀 t; 
    }
    만약  (R> m)복귀 qsum (L, R, rson);
    반환  0 ; 
} 
INT의 C;
INT 의 main () 
{ 
    동안 (CIN >> N C >> >> K) 
    { 
        렙 (I, 1 , C + 1 ) (V) [I]하는 명확한 (), V [i]를 .pb 또 ( 0 ); 
        (빌드 1 N, 1 );
        INT ANS = 0 ; 
        렙 (I, 1 , N) 
        { 
            RI (c); 
            upsum (I, I, C - 1 , 1 N, 1 );

            upsum (V [C] .back () + 1 , I- 1 - 1 , 1 N, 1 ); 
            V [C] .pb 또 (I); 
            INT의 p = (V [C] 크기는 () - K- 1 );
            경우 (p> = 0 ) 
            upsum (V [C] [P] + 1 , V [C] [P + 1 , 1 , 1 , N, 1 );
            INT J = qsum ( 1 N, 1 N, 1 );
            만약 (!의 j는) 계속 ; 
            ANS= 최대 (ANS, I-J + 1 ); 
        } 
        COUT << ANS << ENDL; 
    } 
    반환  0 ; 
}
코드보기

 

추천

출처www.cnblogs.com/bxd123/p/11241725.html