k 개의 작은 문제의 보드 트리 섹션 회장

 

https://www.luogu.org/problem/P3834

#INCLUDE <비트 / stdc ++ H.>
 사용  스페이스 성병; 
타입 정의  LL;
CONST의  INT maxn 2E5 + = 7 ;
INT의 N, m, CNT 루트 [maxn], A [maxn, X, Y, K;
구조체 노드 
{ 
    INT의 L, R, 합; 
} T [maxn * 25 ]; 
벡터 < INT > V;
INT getid ( INT X) 
{ 
    복귀 LOWER_BOUND (v.begin () v.end (), X) -v.begin () + 1 ; 
} 
공극 업데이트 ( INT의 L, INTR, INT 및 X, INT의 Y, INT의 POS) 
{ 
    T [ ++ CNT = T [Y], T [CNT] .sum ++, X = CNT;
    경우 (L == R) ;
    int로 중간 = (L + R) / 2 ;
    경우 (MID> = POS) 업데이트 (좌, 중, T [X] 펜닐, T [Y] 펜닐, POS);
    다른 업데이트 (MID + 1 , R, T [X] .R, T [Y] .R, POS); 
} 
INT의 쿼리 ( INT의 L, INT의 R, INT (X), INT의 Y, INT의 K) 
{ 
    경우 (L == R) 복귀 L;
    INT중간 = (L +에서의 R) / 2 ;
    INT의 합 = T [T [Y] 펜닐] .sum- T [T [X] 펜닐] .sum;
    경우 (합계> = K) 리턴 질의 (좌, 중, T [X] 펜닐, T [Y] 펜닐, K);
    다른  리턴 질의 (MID + 1 , R, T [X] .R, T [Y] .R, K- 합); 
} 
INT 본체 ( 무효 ) 
{ 
    는 scanf ( " %의 D % d에 " , N, m);
    위한 ( int로 I = 1 ; 나는 <= N; ++ i가 ()는 scanf를 " 가 % d " , & A [I]) v.push_back (a [I]); 
    종류 (v.begin (), v.end ());
    v.erase (고유 (v.begin () v.end ()) v.end ()); 
    ...에 대한( int로 I = 1 업데이트는 (i ++; i가 N = <) (1) , N, 루트 [I], 루트 [I- 1 ] getid (a [I]));
    위한 ( int로 난 = 1 난 ++; I <= m ) 
    { 
        는 scanf ( " % D % D % D ' , X, Y, K)을; 
        의 printf ( " % D \ 없음 " , V [질의 ( 1 N, 루트 [X- 1 ], 루트 [Y, K) - 1 ]); 
    } 
    반환  0 ; 
}

 

추천

출처www.cnblogs.com/dongdong25800/p/11605227.html