주제 링크 : http://acm.hdu.edu.cn/showproblem.php?pid=6701
만족 $ 최대를 위해서 타이틀 효과 (A_ {1} A_ {1 + 1} \ cdot \ cdot \ cdot A_ {R}) - (R-L + 1) <= 간격 케이 $의 수.
우선 최대 사전 아웃 접두사 및 접미사 테이블 ST 최대 다음 파티션.
때마다 당신이 간격의 파티션의 최대 범위를 얻을 수 있습니다, 우리는 시간을 필요로 할 때 간격의 최대 값 법적 최대의 수.
여기에서 우리는, 열거 왼쪽 또는 오른쪽 끝 점이 최대의 전류 범위의 위치에 의해 결정된다 선택, 단순화를 통해 합법적 인 권리 점 (왼쪽 점)를 얻기 위해 입력 한 다음, 왼쪽 끝 지점 (오른쪽 끝 지점) 법적 섹션을 열거 할 수 있습니다 왼쪽 때문에 최대 왼쪽과 오른쪽 끝 지점에서 특정 지점 오른쪽 최대에, 그래서 열거하는 쪽의 작은 숫자를 선택해야합니다.
1 #INCLUDE <cstdio> 2 #INCLUDE <CString을> 3 #INCLUDE <알고리즘> 4 #INCLUDE <iostream> 5 #INCLUDE < 설정 > 6 이용한 스페이스 성병; 7 형식 정의 긴 긴 LL; 8 의 typedef 부호 긴 긴 ULL; 9 CONST의 INT maxn = 3e5 + 110 ; 10 INT A [maxn, POS [maxn], L [maxn], R [maxn, 로그인 [maxn]; 11 INT의 N, K; 12 INT의 DP [maxn] [ 20 ]; 13 INT의 쿼리 ( INT의 L, INT의 R) { 14 INT의 K = 로그 [R - L + 1 ]; 15 일 경우 (a> A [DP [R - ([DP [1,5]를 [] K] 1 << k)는 + 1 ] [] K]) 16 리턴 DP [L] [K]을; 17 다른 18 리턴 DP [R - ( 1 << k)는 + 1 ] [K]; 19 } 20 LL DFS ( INT L, INT의 R) { 21 일 경우 (L == R)은 반환 이 [L]을 - 1 <= K 단계; (22) 경우 (L> R) 복귀 0 ; 23 INT의 CNT = 쿼리 (L, R); 24 LL의 ANS = 0 ; 25 일 경우 (CNT - L <R - CNT) { 26 위해 ( int로 I = 1을, 난 = CNT를 <; 내가 ++ ) { 27 개 INT의 LS는 = 최대 (- K - CNT, 난 [CNT를] + 1 ); 28 INT의 RS = 분 (R, R [I]); 29 일 경우 (RS> =의 LS) 30 ANS + = RS - LS + 1 ; 31 } 32 } 33 또 { 34 대 ( int로 된 I = (CNT)를, I <= (R)] 나 ++ ) { 35 INT의 LS = 최대 (L, L [I]); 36 INT의 RS = 분 (I - (a [CNT] - k)는 + 1 , CNT); 37 의 경우 (RS> = 1!) ANS + = RS - LS + 1 ; 38 } 39 } 40 리턴 ANS + DFS (L, CNT - 1 ) + DFS (CNT + 1 , R); 41 } 42 INT 의 main () { 43 의 INT t; 44 는 scanf ( " %의 D ", t); 45 동안 (t-- ) { 46 는 scanf ( " %의 D % d에 " , N, K); (47) 에 대한이 ( int로 I = 1 난 ++; i가 N = < ) 48 (scanf와 " %의 D를 " 및하는 [I]); 49 로그인 [ 0 ] = - 1 ; (50) 에 대한이 ( int로 I = 1 ; i가 N = <; 내가 ++) 로그인 [I] = 로그 [I >> 1 ] + 1 ; 51 대 ( INT난 = 1 ; 난 = <N; I ++ ) (52) DP [I] [ 0 ] = I; 53 대 ( INT의 J = 1 ( 1 << j)는 <= N; J ++ ) { 54 대는 ( int로 I = 1 , I + ( 1 - << j)는 1 ; 나는 ++ <= N ) { 55 의 경우 (a [DP [I] [J - 1 ]> A [DP [I + ( 1 << (j - 1 )) [J - 1 ]]) (56) DP [I] [J]는 DP [I]를 [= J - 1 ]; 57 다른 58 DP가 [I]는 [j]가 DP를 = 난 (+ 1 - << (j 1 [J를 -))] (1) ]; 59 } 60 } 61 대 ( int로 I = 0 POS [I] = 내가 ++; i가 N = <) 0 ; (62) R [N + 1 ] = N; (63) 에 대한이 ( int로 I = N; I> = 1 , 난 - ) { 64 의 경우 (POS [A [I]) { 65 R [I] = POS [A [I]] - 1 ; 66 POS [A [내가] =나는; (67) } (68) 또 { 69 POS [A [I] = I; (70) R [I] = N; 71 } 72 R [I] = 분 (R [I], R [I + 1 ]); 73 } 74 대 ( int로 I = 0 POS [I] = 내가 ++; i가 N = <) 0 ; (75) 에 대한이 ( int로 I = 1 난 ++; i가 N = < {) (76) 의 경우 (POS [A [I]) { 77 L [i]는 POS = [A [I] + 1; 78 POS [A [I] = I; (79) } (80) 또 { 81 POS [A [I] = I; 82 L [I] = 1 ; 83 } 84 L [I] = 최대 (L [i]는, L [I - 1 ]); 85 } 86 의 printf ( " % LLD \ 없음 " , DFS ( 1 , N)); 87 } 88 }