luogu P4198 건물의 재건

이 질문은 경사 세그먼트 트리를 유지한다 "필수"는 요소의 시퀀스 번호를 증가

기타 많은 말을하지 않는, 주요 어려움은 팔 굽혀 펴기의 번호를 업데이트하는 방법에있다

나는 10 분 측정, 뇌사 업데이트 후 절반에 저장된 직접 사용 벡터 순서에 있었다

사실, 당신은 최대 간격을 기록 할만큼, 순서를 기록 할 필요가 없습니다

그러나 지금 직면하고있는 문제는 문제에 대한 해결책을보고 그들이 재귀 처리를 생각 때문에, 어떤 절반 방법이 없다는 것을

즉, 시퀀스 요소의 수를 찾기 위해 사용되는 계수 함수를 증가시키는 범위 내에서 조건을 만족

처음 만 오른쪽 간격으로, 계수 (p의 * 2 + 1, MX [P * 2), 좌측 단면의 최대 값보다 커야 제한 조건을 만족하면서,

하위 상황 :

  L (p) == R (p), 재귀 경계, MX (p)> K를 리턴 할 때 (k는 처음 전달 MX [P * 2]);

  경우 MX (p * 2) <= K, 단순히 우측 부에, 복귀 카운트 (p의 * 2 + 1, K);

  K, 오른쪽 부분은 왼쪽 부분 재귀로 상기 조건을 만족하는 경우 MX [P *이 2> 왼쪽 적어 고려할 때 (그렇지 않은 LEN (p) -len (p * 2) + 카운트 (p의 * 2, k)를 반환 LEN보다는 차폐 부 (p의 * 2 + 1));

( 너무 어렵게 생각 )

코드에서 :

사용법 #include <iostream> 
#INCLUDE <cstdio>
 사용  스페이스 성병;
INT의 N, m;
구조체 노드 {
     INT의 L, R, 렌;
    이중 MX;
    #DEFINE의 L (x)는 t [X] 펜닐
     #DEFINE R (x)는 t [X] .R
     #DEFINE LEN (x)는 t [X] .LEN
     #DEFINE MX (X) t [X] .mx 
} t [ 400010 ];
보이드 빌드 ( INT의 P, INT의 L, INT의 R) { 
    L (p) = L, R (p) = R;
    경우 (L == R)이 {
         리턴 ; 
    }
    int로 중간 = (L + R) >> 1 ; 
    (p 빌드 * 2 , L, MID); 구축 (p의 * 2 + 1 , 중간 + 1 , R); 
} 
INT의 카운트 ( INT의 P, 더블 K) {
     경우 (L (p) == R (p)) 복귀 MX (p)> K;
    경우 (MX (p * 2 ) <= K) 복귀 카운트 (p의 * 2 + 1 , K);
    다른  반환 LEN (p) -len (p * 2 ) + 카운트 (p *를 2 , k)를; 
} 
공극 변화 ( INT의 P,INT의 X, 더블 K) {
     경우 (L (p) == R (p)) { 
        MX (p) = K; LEN (p) = 1 ;
        반환 ; 
    } 
    INT 중간 = (L (p) + R (p)) >> 1 ;
    경우 (X <= MID)의 변화 (p *를 2 , X, K);
    다른 변화 (p의 * 2 + 1 , X, K); 
    MX (p) = 최대 (MX (p * 2 ), MX (p의 * 2 + 1 )); 
    LEN (p) = LEN (p * 2 ) + 카운트 (p의 * 2 + 1 , MX (p * 2 )); 
}
INT 의 main () { 
    는 scanf ( " %의 D % d에 " , N, m); 
    구축 ( 1 , 1 , N);
    반면 (M-- ) {
         이중 X, Y]는 scanf ( " %의 LF의 %의 LF " , X, Y); 이중 황갈색 = Y / X; 
        변화 ( 1 , X, 황갈색)의 printf ( " % D \ 없음 " , LEN ( 1 )); 
    } 
    반환  0 ; 
}

 

추천

출처www.cnblogs.com/SyhAKIOI/p/11617964.html