이 질문은 머리와 poj1823과 동일
나는 또 다른 과제 해결을 참조 할 수 있습니다
유일한 차이점은 그가 가장 왼쪽 찾고 있는지, 우리가 더 자연스럽게 더 왼쪽을 고려할 수있다
현재 L 최대 포인트는 직접 다시 충족하는 경우
그렇지 않으면, 왼쪽 노드에 현재 포인트 티맥스 대회의 왼쪽 아들을 가면
그것은 만약 범위에 걸쳐뿐만 아니라 직접 반환
권리 아들 경우, 그의 아들은 오른쪽으로 갔다
이미 선고 된 특별하지 않을 경우, 그래서 한 번 입력, 그것이 충족해야합니다.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
사용법 #include <iostream> #INCLUDE <큐> #INCLUDE <지도> #INCLUDE <벡터> #INCLUDE <cstdio> #INCLUDE <알고리즘> #INCLUDE <적층> 사용 공간이 수 std; 형식 정의를 오래 오래 LL; CONST INT N = + 1E6 (10) ; CONST INT INF = 0x3f3f3f3f ; 구조체 노드 { INT의 L, R; int로 게으른; INT 티맥스; INT L 최대; INT의 Rmax가; } P [N]; 보이드 팔 굽혀 펴기 ( INT U) { TR [U] .rmax = TR [U << 1 | 1 ] .rmax; 경우 (TR [U << 1 | 1 ] .lazy == - 1 ) TR [U] .rmax + = TR [U << 1 ] .rmax; TR [U] .lmax = TR [U << 1 ] .lmax; 경우 (TR [U << 1 ] .lazy == - 1 ) TR [U] .lmax + = TR [U << 1 | 1 ] .lmax; TR [U] .tmax = 최대 (TR [U << 1 ] .rmax + TR [U << 1 | 1 ] .lmax 맥스 (TR [U << 1 ] .tmax, TR [U << 1 | 1 ] .tmax)); 경우 (TR [U << 1 ] == .lazy TR [U << 1 | 1 ] .lazy) TR [U] .lazy = TR [U << 1 ] .lazy; 다른 { P [U] .lazy = 0 ; } } 보이드 빌드 ( INT U, INT (L), INT (R)) { 경우 (L == R) { TR [U] = (노드) {L, L - 1 , 1 , 1 , 1 }; } 다른 { TR [U] = (노드) {L, R, - 1 }; INT 중간 = L + R >> 1 ; 빌드 (U << 1 , L, MID); 빌드 (U << 1 | 1 중간 + 1 , R); (U)를 팔 굽혀 펴기; } } 보이드 푸시 ( INT U) { TR [U << 1 ] .lazy = TR [U << 1 | 1 ] .lazy = TR [U] .lazy; 경우 (TR [U] .lazy == 1 ) { TR [U << 1 ] .lmax = TR [U << 1 ] .rmax = TR [U << 1 ] .tmax = 0 ; TR [U << 1 | 1 ] .lmax = TR [U << 1 | 1 ] .rmax = TR [U << 1 | 1 ] .tmax = 0 ; } 다른 { TR [U << 1 ] .lmax = TR [U << 1 ] .rmax = TR [U << 1 ] .tmax TR = [u는 << 1 ] .R-TR [U << 1 ] 펜닐 + 1 ; TR [U << 1 | 1 ] .lmax = TR [U << 1 | 1 ] .rmax = TR [U << 1 | 1 ] .tmax = TR [U << 1 | 1 ] .R-TR [U << 1 | 1 ] 펜닐 + 1 ; } P [U] .lazy = 0 ; } 보이드 수정 ( INT U, INT (L), INT (R), INT (X)) { 경우 (TR [U] 펜닐> = 1 && TR [U] .R <= R) { TR [U] .lazy = X; 경우 (X == 1 ) { TR [U] .lmax = TR [U] .rmax = TR [U] .tmax = 0 ; } 다른 { TR [U] .lmax = TR [U] .rmax = TR [U] .tmax = TR [U] .R-TR [U] 펜닐 + 1 ; } 반환 ; } 경우 (TR [U] .lazy! = 0 ) 푸시 (U); INT 중간 TR = [U] 펜닐 + TR [U] .R >> 1 ; 경우 (L <= MID) 수정 (U << 1 , L, R, X); 경우 (R> 중간) { 수정 (U << 1 | 1 , L, R, X); } (U)를 팔 굽혀 펴기; } INT 쿼리 ( INT U, INT K) { 경우 (TR [U] .lmax> = K) 복귀 TR [U] 펜닐] 경우 (TR [U << 1 ] .tmax> = K) 리턴 질의 (U << 1 , K); 경우 (TR [U << 1 ] .rmax + TR [U << 1 | 1 ] .lmax> = K) 복귀 TR [U << 1 ] .R-TR [U << 1 ] .rmax + 1 ; 리턴 질의 (U << 1 | 1 , K); } int로 주 () { INT의 N, m을; CIN >> >> N m; 빌드 ( 1 , 1 , N); int로 난을; 위한 은 (i = 1 ; i가 <= m; I ++ ) { INT C; scanf와 ( " %의 D " , 및 C); 경우 (c == 1 ) { INT의 K; scanf와 ( " %의 D ' , K); 경우 (TR [ 1 ] .tmax < K) { 의 printf ( " 0 \ n " ); 계속 ; } INT TMP = 쿼리 ( 1 , K); 의 printf ( " 가 % d \ n " , TMP); 수정 ( 1 , TMP, TMP + K- 1 , 1 ); } 또 { INT의 L, R; scanf와 ( " % D % D ' , L, R); 수정 ( 1 , L, L + R- 1 - 1 ); } } }