로스 욕심 대륙 밸리 P2184--

포털 : QAQQAQ

 

질문 의도가 : N- $의 $ 간격의 길이로, 매 2 작업 할 수있다 :

폭탄이 이전 구간에서 $ [L, R] $의 종류에 1.

$ [L, R] $ 간격 얼마나 폭탄의 종류 2. 질의

 

아이디어 : 첫 번째 반응은 세그먼트 트리입니다 :하지만 트리 라인을 유지하기 위해 밖으로 생각하고있다

그리고? 폭탄 덮여 간격 길이 때문에 폭탄 변화하지 종류, 변경 및 원인 일 수 있습니다.

최대? 아마 두 개의 완전히 분리 된 간격 폭탄의 두 가지 종류가 있습니다

 

그 간격을 추구하기 전에, 당신에게 범위를 제공하고 간격은 몇 교차 : 우리는이 주제로 변환 할 수 있습니다 : 그래서 우리는 아이디어의 생각을 변경하려면

생각 : 두 개의 간격이 그것의 특성은 무엇인가 교차? 두 간격을 멀리 어떤 특성에서인가? - 두 개의 상 범위 $에서의 L1> $ R2, R1 중 $ <L2 $

이 개 트리 라인을 설립 한 우리 횟수에 $ L의 범위 내에서 유지되어, r에 $가 제공됩니다 : 우리가 쉽게 아이디어를 찾을 수 있습니다

그리고, 각 쿼리 $ L과 R을 $ 들면 $의 [1, L-1] $ 간격 $ $으로의 R & 쿼리 LT 일부 (CNT1)는 $ [R은 N (1) +] $을 $ L $으로 쿼리 갖는다 몇몇 (CNT2), 다음 ($ CNT1 (CNT2) + $) 캔을 감산하여 이전 섹션의 총 수.

(많은 CF1190D의 생각처럼, 존재의 점의 수의 위치를 ​​유지, 일반이 질문은 이산 사용해야합니다 (알수없는) ... CDQ 파티션을 생각)

 

코드 :( 세그먼트 트리 물론,하지만 펜윅의 나무) 더 편리한 것 같다

#INCLUDE <비트 / stdc ++ H.>
 사용  스페이스 성병;
CONST의  INT의 N = 100,050 ; 

INT 합 [ 2 ] [N * 4 ], N, m; // 0 : 1 L, R 
공극 빌드 ( INT의 X, INT의 L, INT의 r)을 
{ 
    경우 (L == R) 
    { 
        합 [ 1 ] [X] = 0 ; 
        합 [ 0 ] [X] = 0 ;
        반환 ; 
    } 
    INT 중간 = (L + R) >> 1 ; 
    X (빌드+ X, L, MID); 
    구축 (X + X + 1 , 중반 + 1 , R); 
} 

공극 업데이트 ( INT의 X, INT의 L, INT의 R은, int로 볼때, INT BL) 
{ 
    경우 (L == R) 
    { 
        합 [BL] [X] ++ ;
        반환 ; 
    } 
    INT 중간 = (L + R) >> 1 ;
    경우 (MID> = POS) 업데이트 (X + X, L, 중간, POS, BL);
    다른 업데이트 (X + X + 1 , 중간 + 1 , R, POS, BL); 
    합 [BL] [X]합 = [BL] [X + X] + 합 [BL] [X + X + 1 ]; 
} 

INT의 쿼리 ( INT의 X, INT의 L, INT의 R, INT의 L, INT의 R, INT BL) 
{ 
    INT RET = 0 ;
    경우 (L> R) 복귀  0 ;
    경우 (L <= 1 && R <= R) 리턴 합 [BL] [X];
    int로 중간 = (L + R) >> 1 ; 
    경우 (MID> = L) + = RET 쿼리 (X + X, L, 중, L, R, BL);
    경우 (MID <R) RET + = 쿼리 (X + X + 1 , 중간 + 1 , R, L, R, BL);
    반환 RET를; 
} 

INT 의 main () 
{ 
    INT의 합 = 0 ; 
    scanf와 ( " %의 D % d에 " , N, m);
    반면 (M-- ) 
    { 
        의 INT (X)는, Y가 해제; 
        scanf와는 ( " % D % D % D " , 및, (X)을 선택, Y);
        경우 (최적화 된 == 1 ) 
        { 
            업데이트 ( 1 , 1 , N, X, 0 ); 
            업데이트 ( 1 , 1 , N, Y, 1 ); 
            합집합++ ; 
        } 
        다른 
        { 
            INT는 지금 = 0 ; 
            지금 + = 쿼리 ( 1 , 1 , N, Y + 1 , N, 0 ); 
            지금 + = 쿼리 ( 1 , 1 , n은 1 , X- 1 , 1 ); 
            의 printf ( " % D \ 없음 " , sum- 지금); 
        } 
    } 
    반환  0 ; 
}
코드보기

 

추천

출처www.cnblogs.com/Forever-666/p/11306355.html