[2019 꽉 전기 멀티 열 번째 학교 필드] [hdu6701] Rounddog 행복합니다

주제 링크 : 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 }

 

추천

출처www.cnblogs.com/sainsist/p/11414393.html