HDU 4553 약속 (두 개의 세그먼트 트리 유지 보수 간격)

포함

포함

포함

포함

포함

포함

포함

포함

오래 오래 LL 정의

위한 (I, L, R)에 대해 정의 (I = 1에서 INT; I <= R; I ++)

정의 INF 1 << 30

EPS를 정의 (1E-9)

LSON (p)를 정의 (p를 << 1)

rson (p)를 정의 (p << 1 | 1)

네임 스페이스를 사용하여 표준;
쌍 타입 정의 <INT, INT> PII;
CONST INT의 N = + 1E5 (30);
INT의 N, m;
구조체 노드 {
INT의 L, R;
INT의 lsum, rsum, SSUM;
} A [N << 2], B [N << 2];

push_up 공극 (RT의 INT, INT의 L, R & 중위 INT)은 {
MID = (L + R 및 LT)에 >> 값 int 1;.
. A [RT] = .lsum A [LSON (RT)] lsum를 // 왼쪽 연속 좌측 서브 트리 업데이트 공간 아버지
A [RT] .rsum은 [A = rson (RT)]를 rsum ;. // 오른쪽 공간 지속적으로 업데이트 아버지의 우측 서브 트리
// 총 연속 공간 맥스 (총 연속 연속 우측 서브 트리 전체의 좌측 서브 트리 좌측 및 우측 서브 트리 연속하는 일련 번호는 + 우측 서브 트리) 왼쪽
A [RT] .ssum = 최대 (최대 (A [LSON (RT)]. SSUM, A [rson (RT)]. SSUM) A [LSON (RT를 ..)] Rsum + A [rson (RT)] lsum)
.. IF (A [LSON (RT)] + L-lsum MID == 1) A [RT] = A + .lsum [rson (RT)] .lsum // 좌측 서브 트리 전체 왼쪽 연속 좌측 서브 트리를 포함 아버지의 좌측 및 우측 서브 트리의 지속적인 확장 계속 남아
있으면 (. A [rson (RT )] rsum을 == R-MID) A [RT] . .rsum = A + [LSON (RT)] Rsum;
B [RT] .lsum = B [LSON (RT)] lsum ;.
B [RT] .rsum = B [rson (RT)] Rsum ;.
B [ RT] .ssum = 최대 (최대 ( B [LSON (RT)]. SSUM, B [rson (RT)]. SSUM), B [LSON (RT)]. rsum + B [rson (RT)]. lsum) ,
(.. B [LSON (RT)] + L-lsum MID == 1) IF B [RT] = B + .lsum [rson (RT)] lsum;
경우. (B [rson (RT)] == rsum R-MID) [RT] .rsum + = B [LSON (RT)] B rsum.;

}

push_down 공극 (RT의 INT, INT의 L, R & 중위 INT) {
MID = (L + R 및 LT)에 >> int로 1].
IF (A [RT] + L-R 및 LT == .ssum 1.) {// 아버지 덮었다 서브 간격 또한 적용된다
. ..., A [LSON (RT)] lsum = A [LSON (RT)] Rsum = A [LSON (RT)] SSUM = MID-L + 1
. A [rson (RT)] lsum = A [rson (RT)] Rsum = A [rson (RT)] SSUM = MID-R & LT; ..
}를 다른 IF (A [RT] .ssum == 0) {// 빈 감각 비어 부 아버지, 아들
이 [ LSON (RT)] lsum = A [LSON (RT)] Rsum = A [LSON (RT)] SSUM = 0; ...
. A [rson (RT)] lsum = A [rson (RT)] = Rsum. . A [rson (RT)] SSUM = 0;
}
IF (B [RT] + L-R 및 LT == .ssum 1.) {
... B [LSON (RT)] lsum = B [LSON (RT) = Rsum B [LSON (RT)] SSUM = MID-L + 1 ;..
... B [rson (RT)] lsum = B [rson (RT)] Rsum = B [rson (RT)] SSUM = R & LT-MID;
IF 다른} (B [RT] .ssum == 0) {
B [LSON (RT)] lsum = B [LSON (RT)] Rsum = B [LSON (RT)] = 0 ... SSUM;
B [보로 (3 월)] lsum = B [보로 (3 월)]에 rsum = B [보로 (3 월)] = 0 SSUM...;
}
}

빌드 {공극 (INT 연구 르, INT 재 INT)
[R] .lsum = (재 르 + 1) B A [R] = .lsum 단계;
A [R] .rsum = B [R] .rsum = (재 르 + 1);
A [R] .ssum = B [R] .ssum = (재 르 + 1);
A [R] 펜닐 = 제작하는 [R] = .R 재;
B [R] 펜닐 = 르, B [R] = .R 재;
(레 == 재) 돌아 가면;
INT 중간 = (레 + 재) >> 1;
(제작 : LSON (R), 중간)를 구축;
구축 (rson (r)을 중간 + 1, 재);
}

보이드 업데이트 (INT 연산, INT의 L, INT의 R, INT의 RT) {
경우 (A [RT] 펜닐> = 1 && A [RT] .R <= R) {
경우 (OP == 1) {// DS更新自己
A가 [RT] .lsum은이 [RT] .rsum가 = A [RT] .ssum = 0;
} 다른 경우 (OP == 0) {// NS更新两棵树
A가 [RT] .lsum은이 [RT] .rsum가 = A [RT] .ssum = 0;
B [RT]의 .lsum = B [RT]의 .rsum = B [RT] .ssum = 0;
사용한다} else {//两棵树清空
A [RT] .lsum = A [RT] .rsum = A [RT] .ssum = A [RT] .ra [RT] 펜닐 +1 단계;
B [RT]의 .lsum = B [RT]의 .rsum = B [RT]의 .ssum = B [RT] .rb [RT] 펜닐 +1 단계;
}
반환;
}
INT 중간 = (A [RT] 펜닐 + A [RT] .R) >> 1;
push_down (RT, A [RT] 펜닐, A [RT] .R); //下方标记
(L <= MID) 만약 업데이트 (OP, L, R, LSON (RT));
경우 (R> MID) 업데이트 (OP, L, R, rson (RT));
push_up (RT, A [RT] 펜닐, A [RT] .R); //上提标记
}

쿼리 INT (INT OP, RT의 INT, INT LEN) {
(A [RT] .L를 A [RT]을 == .R) IF A [RT] .L 리턴;
push_down (RT, A [RT] .L을하는 [RT]을 .R)
int로 MID = (A [RT] .L + A [RT] .R) >> 1;.
IF (OP) {// DS
IF (A [LSON (RT)]. SSUM> = LEN)
쿼리 리턴 (OP를 LSON (RT), LEN)
있습니다 .. 다른 IF (a [LSON (RT)] + Rsum A [rson (RT)] lsum> = LEN) // 좌측 서브 트리를 더한 우측 부 좌측 및 우측 서브 트리 간격 만족은
반환 미드 A [LSON (RT )] rsum +1 ;. // 개시 좌측 서브 트리에 있어야
다른
반환 쿼리 (OP, rson (RT), LEN)
} // 밖의 {NS를
. (B [LSON (RT)] SSUM> = LEN) IF
쿼리 리턴 (OP를 LSON (RT), LEN)
있습니다 .. 다른 IF (B [LSON (RT)] Rsum + B [rson (RT)] lsum > = LEN)
반환 MID-B [LSON (RT)] + +1 Rsum ;.
다른
반환 쿼리 (OP가 rson (RT), LEN);
}
}
숯 OP [20이다];
공극 해결 (INT 캐스) {
의 printf ( "케이스 % D : \ 않음", CAS);
scanf와 ( "% d 개 %의 D", 및 N, m);
(1,1, N)를 작성;
INT의 L, R;
(I, 1, m) {FOR
는 scanf ( "% S %의 D", OP, l);
경우 (OP [0] == 'D') {
경우 (a [1] .ssum> = 1) {
INT 볼때 쿼리 = (1,1, l);
의 printf (POS "% d를,의는 \ n을 비행하자");
업데이트 (1, POS, POS + L-1,1);
} 다른 {
풋 ( "자신과 비행");
}
} 다른 경우 (OP [0] == 'N') {
(a [1] .ssum> = 1) {경우
INT 볼때 쿼리 = (1,1, l);
의 printf (POS "% d를, 내 게지 \ 없음을 넣지 마십시오");
업데이트 (0, POS, POS + L-1,1);
다른 경우} {([1] .ssum> = 1 b)
INT 볼때 쿼리 = (0,1, l);
의 printf ( "%의 D, 단 '


풋 ( "나를 위해 대기");
}
} 또 {
는 scanf ( "%의 D", R);
업데이트 (2, L, R, 1);
의 printf ( "나는 \ n을! 중국어 chengxuyuan의 희망입니다");
}
}
}
INT의 main () {
INT의 t;
scanf와 ( "%의 D", t);
(1 = 1에서 INT; I <= t; I ++) {
(I) 해결;
}
0을 반환;
}

추천

출처www.cnblogs.com/xxrlz/p/11359693.html