연속 간격 세그먼트 트리

 

질문의 의미 : 일련의 인공 지능 부여

LR 만족 묻는 A [L] -a [R]에서 [L] -a [R은 인접한 디지털 차이의 차이가 1보다 크지 사이의 정렬의 수가 얼마나

 

게임은 단순히 단서가 부족 매우 영리한 트리 라인

 

각 L 및 유지 보수가 단조로운 CNT 스택과 함께 수행 할 수 있도록, 다음 마지막을 유지하기 위해 사용 수정해야 할 수도 있습니다

즉 그래서 쌍은 R의 LR의 L 합류마다 때문에 = R이 소정의 최소 조건을 만족하기에 확실한 -1 최소값 -1 그래서 응답이 만족시켜야 -1 빌드 초기화가없는 것을 의미 값이 될 수있다 

#INCLUDE <비트 / stdc ++ H.>
 사용  스페이스 성병;
#DEFINE에 대해 담당자는 (i, a가, b) (; 제가 (a) = int로 <= (b)] 나 ++)
 #DEFINE에 대한 REPP을 (I, a가, b) (INT I = (a) I> = (b) - I)
 #DEFINE가 긴 긴 것이다
 #DEFINE (X) (cerr << (#의 X) << '='<< (X) << ENDL) 참조
 #DEFINE의 0x3f3f3f3f INF
 #DEFINE의 CLR (A을 , V)가 memset (A · V를 sizeof A)
 ///////////////////////////////// / 
CONST의  INT의 N = 1E5 + 10 ; 

INT 미네소타 [N << 2 ], T [N << 2 ], N, m, COL [N << 2 ], A [N]; 
; ANS LL

{
     (미네소타 [POS << 1 ] == 미네소타 [POS << 1 | 1 ]) 
    미네소타 [POS] = 미네소타 [POS << 1 ], t [POS = t의 [POS << 1 ] + t [POS << 1 | 1 ];
    다른  경우 (미네소타 [POS << 1 ] <미네소타 [POS << 1 | 1 ]) 
    미네소타 [POS] = 미네소타 [POS << 1 ], t [POS = t의 [POS << 1 ];
    다른 미네소타 [POS = 미네소타 [POS << 1 | 1 ], t [POS = t의 [POS << 1 | 1 ];
POS) 
{ 
    경우 ! (COL [POS]) ; 
    COL [POS << 1 ] + = COL [POS]; 
    COL [POS << 1 | 1 ] + = COL [POS]; 
    미네소타 [POS << 1 ] + = COL [POS]; 
    미네소타 [POS << 1 | 1 ] + = COL [POS]; 
    COL [POS는] = 0 ; 
} 
공극 빌드 ( INT의 L, INT의 R, INT의 POS) 
{    
    COL [POS] = 0 ;
    만약(L == R) {미네소타 [POS] = 0 ; t [POS] = 1 ; 반환 }
     INT m = (L + R) >> 1 (L, m, POS 구축 << 1 ) 작성 (m + 1 , R, POS << 1 | 1 ); 
    최대 (POS); 
} 
공극 UPsum ( INT의 L, INT의 R, INT의 V, INT의 L, INT의 R, INT의 POS) 
{ 
    경우 (L <= 1 && R <= R) {COL [POS는] + = V; 미네소타 [POS는] + = V; 반환 }
     INT m = (L + R) >> 1 ; 다운 (POS);
    만약(L <= m) UPsum (L, R, V, L, m, POS << 1 );
    경우 (R> m) UPsum (L, R, V, m + 1 , R, POS << 1 | 1 ); 
    최대 (POS); 
} 
스택 < INT > mA, MI;지도 < INT , INT > MP;
INT 의 main () 
{ 
    INT의 CAS; CIN >> CAS; INT 카세 = 0 ;
    반면 (cas-- ) 
    {    
        mp.clear (); 
        동안 (! ma.empty ()) ma.pop ();
        동안 (! mi.empty ()) mi.pop (); 
        ANS =0 ; 
        scanf와 ( " %의 D ' , N); 
        (빌드 1 N, 1 ); 
        렙 (I, 1 , N)는 scanf ( " %의 D " , & A [I]);
        INT 사전; 
        렙 (I, 1 , N) 
        { 
            동안 (! ma.empty ()) // 维护单调递减
            {
                 INT의 K = ma.top ();
                경우 (a [K]는>은 [I] =) 휴식 ; 

                ma.pop (); 
                경우 (ma.empty ()) 프리 = 1;
                다른 사전 ma.top = () + 1 ; 
                UPsum (프리, K, -a [K], 1 N, 1 ); 
            } 
            경우 (ma.empty ()) 프리 = 1 ;
            다른 사전 ma.top = () + 1 ; 
            ma.push (I); 
            UPsum (프리, I, A [i]를, 1 N, 1 ); 

            반면 (! mi.empty ()) 
            { 
                INT의 K = mi.top ();
                경우 (a [K] <= A [I]) 분해 ; 
                mi.pop (); 
                경우 (mi.empty ()) = 프리1 ;
                다른 사전 mi.top = () + 1 ; 
                UPsum (프리, K, A [K], 1 N, 1 ); 
            } 
            경우 (mi.empty ()) 프리 = 1 ;
            다른 사전 mi.top = () + 1 ; 
            mi.push (I); 
            UPsum (프리, I, -a [I], 1 N, 1 ); 

            만약 (! MP [A [I]) 사전 = 1 ;
            다른 사전 MP = [A [I] + 1 ; 
            UPsum (프리, I, - 1 , 1 , n은 1 );
            MP [A [I] = I; 
            ANS + = t [ 1 ]; 
        } 
        의 printf ( " 케이스 # % d의 %의 LLD \ 없음 " , ++ 카세, ANS); 
    } 
}
코드보기

 

추천

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