단지 문제에 새겨 솔루션을 끌어 올 가자 [안개]
최근 그는 자신에게 검토를 시작하기 전에 그렇게 배운 이상한 가난한 기본적인 것들을 발견, 난 그냥 거의 완전하게 학습 한 후 루오 구 필드 시험을 열지 않았다 트리의 회장 ...
나는 그런 콤보 제목을 발견했다.
실제로,이 문제는 제 50 %, 다른 채널 후 50 % 해당하고, 두 개의 부분으로 분할된다. 관측 데이터 범위, 우리는 두 개의 범위가 매우 다양 타겟으로하는 표시되므로 분리 할났습니다.
자세히 살펴보면, 1,000 이하의 페이지 페이지의 범위는 단일 나방을 할 수있는 범위의 것을 암시하는 것 같다.
매트릭스, C, 및 R의 발행 이전에 50 % 미만의 200와 같다. (I, J)의 발생 회수와 누적 내 - 특정 높이 직사각형 내 요청 Couchu 제목은 단지 매우 작은 범위는, 그 이차원 접두사는 (1,1)의 높이를 어떻게 각 페이지를 기록하는 것을 생각할 수있다 높이, O (CRP)의 시간 복잡도. 다음에 P 레인지 하강 페이지 높이 각 질의 및 O (p)의 축적 시간 복잡도의 수.
50 % (R) = 1 일 이후의 시퀀스는 문제가된다. 페이지가 아직 열거 높이 내림차순 경우 기간 필요한 높이 범위 Couchu 요구는, 사전 처리의 복잡성을 허용하지 않다. 그러나, 데이터의 플러스 또는 마이너스 범위의 모든 범위의 특정 기간 ,이 나무 ...의 이사회 의장 인 O (nlogn)의 시간 복잡도, 공간 복잡도 O (nlogn)가 .
내가 냄비 밖으로 문의 후, 트리의 숙련 회장을 쓰기 그래서. 재귀 쿼리가 잎 노드에왔다,이 접두사 위에서 설명한 것과 페이지의이 종류의 당신이에 가입하려는로처럼되어야하는 대답을 생산하는 방법에 많은 기여. 그러나, 나는 두 번째 샘플의 결과로, 직접 반환 일까지라고 나에게 시간이 오래 붙어 있습니다 ...
코드 :
사용법 #include <iostream> #INCLUDE <cstdio> 사용 스페이스 성병; INT의 R, C, m, X1, X2, Y1, Y2; INT CNT [ 210 ] [ 210 ] [ 1010 ], ANS; 긴 긴 합 [ 210 ] [ 210 ] [ 1010 ], H, NUM; CONST의 INT의 로그 = 20 ; INT T [ 500010 ], L [ 500,010 * 로그], R [ 500,010 * 로그] SUM [ 500,010 * 로그, CNT [ 500,010 * 로그]; INT의 어린 아이; 빈(빌드 INT & P, INT의 L, INT의 R) { P = ++ TOT 단계; 경우 (L == R) 창 ; int로 중간 = (L + R) / 2 ; (L의 [피], L, MID) 구축; 빌드 (R [P], 중간 + 1 , R); } 공극 업데이트 ( INT & P, INT의 전, INT의 L, INT의 R, INT의 X) { P = ++ TOT 단계; L [P] = [중고] L은 R [P]가 [중고]을 R = CNT [P] = CNT [중고] + 1 , SUM [P] = SUM [중고] + (X); 만약(L == R) 창 ; int로 중간 = (L + R) / 2 ; 경우 (X <= MID) 업데이트 (L [P], L [중고], L, 중, X); 다른 업데이트 (R [P], R [전, 중간 + 1 , R, X); } INT 쿼리 ( INT (X), INT의 Y, INT의 L, INT의 R, 긴 길이 H) { INT 중간 = (L + R) / 2 ; 경우 (L == R) { 경우 (H % 리터 == 0 ) 복귀 H / L; 다른 창 H / ℓ + 1; } INT 브로 = 0 ; 경우 (SUM [R [Y] - SUM [R [X]> = H) 리턴 질의 (R [X], R [Y], 중간 + 1 , R, 1H); 다른 경우 (SUM [R [Y] - SUM [R [X] == H) 반환 CNT [R을 [Y] - CNT [R의 [X]; 또 { 발 + = CNT [R [Y] - CNT [R의 [X]; 반환 브로 + 쿼리 (L를 [X], L [Y], L, 중간, H-SUM [R [Y] + SUM [R [X]); } } INT 의 main () { 는 scanf ( " % D % D % D " , R, C, m); 만약 (R ==의 1 ) { 빌드 (T [ 0 ], 1 , 1000 ); 위한 ( int로 I = 1 , X, 난에 c = <; 내가 ++ ) { 는 scanf ( " %의 D ' , X)을; 업데이트 (T [I], T [I - 1 , 1 , 1000 , X); } 에 대해 ( int로 I = 1 ; I <= m; 내가 ++ ) { 는 scanf ( " % D % D % D % D % LLD " , X1, Y1, X2, Y2, 1H); NUM = 0 , ANS = 0; 경우 (SUM [T [Y2] - SUM [T [Y1- 1 ] <H)의 printf ( " 불량 QLW \ n을 " ); 또 { ANS = 쿼리 (T [Y1- 1 ], T [Y2], 1 , 1000 , 1H); 의 printf ( " % D \ 없음 " , ANS); } } } 또 { 위해 ( int로 I = 1 ; I <= (R)] 나 ++ ) { 위해 ( INT의 J = 1 , X, J <= C, J ++ ) { 는 scanf (" %의 D ' , X); 대 ( INT의 p = 1 ; p <= 1,000 ; P ++ ) { CNT [I] [J] [P] = CNT [I] [J = 1 ] [P] + CNT [Ⅰ- 1 ] [J] [P ] -cnt [Ⅰ- 1 ] [J = 1 ] [P]; 합 [I] [J] [P] = 합계 [I] [J = 1 ] [P] + 합 [Ⅰ- 1 ] [J] [P] -sum [Ⅰ- 1 ] [J = 1 ] [P ]; } CNT [I] [J] [X] ++ ; 합 [I] [J] [X] + =엑스; } } 에 대해 ( int로 I = 1 ; I <= m; 내가 ++ ) { 는 scanf ( " % D % D % D % D % LLD " , X1, Y1, X2, Y2, 1H); NUM = 0 , ANS = 0 ; 대 ( INT의 p = 1,000 ; p> = 1 ; p-- ) { 경우 (NUM + 합 [X2] [Y2] [P] + 합 [X1- 1 ] [Y1- 1 ] [P] -sum [X2 [Y1- 1 ] [P] -sum [X1- 1 ] [Y2] [P]> = H) { 긴 길이 차 = H-확실히; 만약 (! (차의 % P)) { ANS + 차 / P; } 그렇지 { ANS + 차 / P + 1 ; } 확실 + I = [X2] [J2] [J] + m [X1- 1 ] [Y1- 1 ] [J] -sum [X2] Y1- 1 ] [J] -sum [X1- 1 ] Y2] [J]; 휴식 ; } 그렇지 { 확실 + I = [X2] [J2] [J] + m [X1- 1 ] [Y1- 1 ] [J] -sum [X2] Y1- 1[P] -sum [X1- 1 ] [Y2] [P]; ANS + = CNT [X2] [Y2] [P] + CNT [X1- 1 ] [Y1- 1 ] [P] -cnt [X2] Y1- 1 ] [P] -cnt [X1- 1 ] [Y2 ][피]; } } 경우 (NUM> = H)의 printf ( " % D \ 없음 " , ANS); 다른 사람 의 printf ( " 불량 QLW \ n을 " ); } } 반환 0 ; }