꽉 전기 멀티 보정 번째 필드 1,012 L - 최장 부분 배열 CE 세그먼트 트리

이 문제는 정말 쇼이다. . . 나는했다. . . 기록 할 수있는 좋은 느낌 세그먼트 트리. . .

주제 효과 : 당신에게 문자열을 줄 수는 가장 긴이 긴 다음 조건을 충족하도록 요청 문자열 : K의 발생보다는 각 번호, 또는이 아이가 가진 노 쇼의 문자열, 또는 그 이상의하십시오.

우리는 내가 확실히 먼이 조건을 충족 왼쪽 찾을 수 있도록 노력하겠습니다 각 위치는 다음 최대하지 미야을 유지 존중?

그렇다면 우리는 먼이 조건을 충족 찾을 수 있습니까? ? ? 그래서 우리는 몇 가지 물건을 유지해야합니까?

우리는 [] t 배열을 유지하는, t [J] = m 내가 j 위치에서 왼쪽으로 비트를 나타내며, 조건 만족 수가 유지 세그먼트 트리 (하나를 0으로는 K와 동일하거나보다 크다).

각각의 위치 나, 우리는 현재에서의 현재 위치에 대표 점을 C-1 추가 0 구간의 길이가 필요

우리는 t [I]를 논의 할 때마다 상기 I 위치 때 우측 지점으로서 [I] =의 X, X 좌측 지점을 제외한 나머지의 수 난 [I, I]이 범위로서 위치 될 수 있도록 X는 다른 0 번 등장된다 번만 내에 등장 0 확실히 가능하다 표시되므로 제 더하기 C-1 (-1 위치 때문에 더욱 실용적인 좌측 지점 (X)로 설명 할 필요가있는 경우)

그렇다면 우리 수가 의한 i 번째 위치에 [I] 나 위치, a는 [I] 위치의 값과 동일하게 사용 된 간격이 가능하도록 위치에 [I], 그 결과, 현재 위치가 나타난 고려 하지만 지금은되지. 우리는 필요

하나 개의 위치로부터 -1의 전체 값, a는 [I]의 간격을 더 이상 사용할 수 없습니다 나타내는 것이다. 그리고, (K)의 현재 위치에서 우리의 전방에 [I] 앞에 위치의 K-1 [I]의 위치의 이전 위치를 사용할 수 없지만, 오른쪽은 추가 이후 새로운 A [i]를 이 섹션을 사용할 수없는 사용할 수있게 될 것입니다, 원래의 값을 나타내는, 일의 범위 내에 있어야는 사용할 수 없습니다 사용할 수 있습니다.

#INCLUDE <. 비트 / stdc ++ H>
 #DEFINE가 긴 긴 LL
 #DEFINE의 LSON의 RT << 1
 #DEFINE의 rson의 RT << 1 | 1
 사용  스페이스 성병;
CONST의  INT의 맥스 1E5 + = 6 ;
구조체 노드 {
    INT의 L, R;
   INT , 탄소 나노 튜브를 게으름 피우다; 
} 트리 [맥스 << 2 ];
int로 A [맥스]을;
INT 사전 [맥스];
int로 N, C, K; 
벡터 < INT > G [맥스];
보이드 push_down ( INT의 RT) {
    경우 + = (트리 [RT] .laze) {
      트리 [LSON] .CNT 트리 [RT] .laze; 
      트리 [rson] .CNT + = 트리 [RT] .laze; 
      트리 [LSON] .laze + = 트리 [RT] .laze; 
      트리 [rson] .laze + = 트리 [RT] .laze; 
      트리 [RT] .laze = 0 ; 
   } 
} 
공극 buildtree ( INT의 RT, INT의 L, INT의 R) { 
    트리 [RT] 펜닐 = L 단계; 
    트리 [RT] .R = R; 
    트리 [RT] .laze = 0 ; 
    트리 [RT] .CNT = 0 ;
    경우 (L의 == 된 R) {
        반환 ;
    } 
    INT 중간 = (L + R) >> 1 ; 
    buildtree (LSON, L, MID); 
    buildtree (rson 중간 + 1 , R); 
} 
공극 업데이트 ( INT RT, INT UL, INT 우르 INT w) {
     INT의 L = 트리 [RT] 펜닐;
    INT의 R = 트리 [RT] .R;
    만약 UL (<= 1 && R <= UR) { 
        트리 [RT] .CNT + = w; 
        트리 [RT] .laze + = w;
        반환 ; 
    } 
    push_down (RT); 
    INT 중간 = (L + R) >> 1 ;
    경우 (UR <= MID) { 
        업데이트 (LSON, UL, UR, w); 
    } 다른  경우 (UL> 중간) { 
        갱신 (rson, UL, UR, w); 
    } 다른 { 
        갱신 (LSON, UL, 중간, w); 
        업데이트 (rson, 중간 + 1 , UR, w); 
    } 
    트리 [RT] .CNT = 최대 (트리 [LSON] .CNT, 트리 [rson] .CNT); 
} 
INT 쿼리 ( INT RT) {
     INT의 L = 트리 [RT] 펜닐;
    INT의 R = 트리 [RT] .R;
    경우 (L의 == 된 R) {
         복귀 L; 
    } 
    (RT) push_down; 
    int로 중간 = (L + R) >> 1 ;
    경우 (트리 [LSON] == .CNT c) {
         리턴 질의 (LSON); 
    } 다른  경우 (트리 [rson] == .CNT c) {
         리턴 질의 (rson); 
    } 다른 {
         반환 - 1 ; 
    } 
} 
INT 의 main () {
   동안 (~는 scanf ( " % D % D % D " , N, C, K)) {
       위해 ( int로 I = 1 ; 나는 =에 c <; 내가 ++ ) {
        G [I]하는 명확한 (); 
        G [I] .push_back ( 0 ); 
      } 
      memset 함수 (프리, 0 , 는 sizeof (예정));
      위한 ( int로 I = 1 ; 나는 <= N; I ++는 ) { 
        는 scanf ( " %의 D를 " , & A [I]); 
        . G [A [내가]와 push_back (I); 
      } 
      buildtree ( 1 , 1 , N);
      경우 (K ==의 1 ) { 
        의 printf ( " % D \ 없음 " , N);
        계속 ; 
      } 
      INT ANS = 0 ;
      위한 ( int로 I = 1 ; i가 <= N; 내가 ++ ) {
          INT (X) = A [I];
         INT p = ++ 미리 [A [I]; 
         업데이트 ( 1 , I, I, C- 1 );
         경우 (G [A [I] [P- 1 ] + 1 <= G [A [I] [P] - 1 ) 
            업데이트 ( 1 , G [A [I] [P- 1 ] + 1 , G [A [I] [P] - 1 - 1 );
         경우 (p> = K) 
            업데이트 ( 1 , G [A [I] [PK] + 1 , G [A [I] [PK +1 , 1 );
         INT POS = 쿼리 ( 1 );
         경우 (POS =! - 1 ) { 
            ANS = 최대 (ANS I-POS + 1 ); 
         } 
      } 
      의 printf ( " % D \ 없음 " , ANS); 
  } 
  반환  0 ; 
}

 

추천

출처www.cnblogs.com/bluefly-hrbust/p/11420399.html