기술
Bytetown, AB, 시민들은 시장 선거 캠페인에 후보자가 자신의 변덕에 모든 장소에서 자신의 선거 포스터를 배치 한 것을 참을 수 없었다. 시의회는 마지막으로 다음과 같은 규칙을 포스터를 배치하기위한 선거 벽을 구축하고 도입하기로 결정했다 :
모든 후보가 벽에 정확히 하나의 포스터를 배치 할 수 있습니다.
모든 포스터는 벽의 높이와 같은 높이가 동일하다; 포스터의 폭 (바이트 Bytetown 길이의 단위 임) 바이트의 임의의 정수가 될 수있다.
벽은 세그먼트로 분할되고, 각 세그먼트의 폭은 1 바이트.
각 포스터는 완전히 벽 세그먼트의 연속 수를 포함해야합니다.
그들은 (모든 후보에 대한 충분한 장소가되도록) 10000000 바이트 벽을 구축했다. 선거 캠페인이 다시 시작되었을 때, 후보자는 벽에 자신의 포스터를 배치하고 그들의 포스터 폭 넓게 달랐다. 또한, 후보자는 이미 다른 포스터에 의해 점령 벽 세그먼트에 자신의 포스터를 배치하기 시작했다. Bytetown에서 모두가 그 포스터 선거 전 마지막 날에 (전부 또는 일부) 볼 수 호기심이었다.
당신의 임무는 모든 포스터는 포스터 '크기, 선거 벽에 배치의 자신의 위치와 순서에 대한 정보를 제공 해 놓으면 볼 포스터의 수를 찾는 것입니다.
입력
입력의 첫 줄 따라 케이스의 수를 나타내는 (C)들을 포함한다. 하나의 경우에 대한 데이터의 제 1 라인 수를 포함 <= N <= 10000 이후 N 라인들이 배치 된 순서의 포스터를 설명한다. N 개의 라인들 중 i 번째 라인은 각각 좌단의 점유 벽 세그먼트의 수와 i 번째 포스터 우단, 두 정수 번호 리튬 및 RI를 포함한다. 우리가 알고있는 각 1 <= I는 <= N, 1 <= 리 <i 번째 포스터가 배치 된 후, 완전히 리, L 번호가 모든 벽 세그먼트를 커버 = RI <= 10000000 I + 1, ... , 리.
산출
모든 포스터 배치 한 후 각각의 입력 데이터 세트 볼 포스터의 수를 출력한다.
아래 그림은 샘플 입력하는 경우를 도시한다.
샘플 입력
1
5
1 4
2 6
8 10
3 4
7 10
샘플 출력
4
핵심 아이디어 :
세그먼트 트리.
벽의 길이가 너무 길면 인해, 별도의 제 다음 성과 같은 많은 어레이를 열지 않도록.
다음과 같이 코드입니다 :
. (1) #INCLUDE <cstdio> 2 #INCLUDE <iostream> . (3) #INCLUDE <알고리즘> 4. 은 USING 공간 STD] . 5 의 typedef 긴 롱 LL] . 6 CONST의 INT N = 1E4 + 20이다 ] . 7 INT의 B [N << 1이다. ], D [N << . 1 , CD는, 추 [N <<] . 1 ], CNT . 8 // 데이터 준비 이산 저장 . 9 구조체 노드 { 10 INT의 L, R & LT를] . 11 } A [N] (12)이 구조체 TNODE { 13는 INT는L, R, 합계 지연; 14 } TR [N << 3 ]; (15) 보이드 푸시 ( INT의 m) 16 { 17 INT의 t =에서의 TR [m] .lazy; 18 의 경우 (t =! - 1 ) 19 { 20 TR [m << 1 ] .lazy = t; 21 TR [m << 1 | 1 ] .lazy = t; 22 } 23 TR [m] .lazy = - 1 ; 24 복귀 ; 25 } 26 무효빌드 ( INT의 m, INT의 L, INT R) 27 { 28 TR [m] 펜닐 = L; 29 TR [m] = .R R; 30 TR [m] .lazy = - 1 ; 31 의 경우 (L == R) 32 리턴 ; 33 INT 중간 = (L +의 연구) >> 1 ; 34 빌드 (m << 1 , L, MID); 35 빌드 (m << 1 | 1 중간 + 1 , R); 36 창 ; 37 } 38 보이드 업데이트 ( INT의 m, INT의 L, INT의 R, INT의 V) 39 { 40 의 경우 (TR [m] 펜닐 == L && TR [m] .R == R) 41 { 42 TR [m] .lazy = V; 43 창 ; 44 } 45 푸시 (m); 46 INT 중간 = (TR의 [분] 펜닐 + TR [m] .R) >> 1 ; (47) 의 경우 (R <= MID) 48 업데이트 (m << 1 , L, R, V); (49) 그 밖의 경우 (L> MID) 50 업데이트 (m << 1 | 1 , L, R, V); 51 다른 52 { 53 업데이트 (m << 1 , L, 중간, V); 54 업데이트 (m << 1 | 1 중간 + 1 , R, V); 55 } 56 창 ; 57 } 58 무효 쿼리 ( INT의 m) 59 { 60 의 경우 (TR의 [분] 펜닐 == TR [m] .R) 61 { 62 추 [CNT ++ = 용 TR [m] .lazy; 63 창 ; 64 } 65 푸시 (m); 66 쿼리 (m << 1 ); 67 쿼리 (m << 1 | 1 ); 68 } 69 INT getid ( INT X) 70 { 71 반환 LOWER_BOUND (D, D + CD, X) -D- + 1 ; 72 } 73 INT 의 main () 74 { 75 INT의 T; 76 CIN >> T; (77) 동안 (T-- ) 78 { 79 INT엔; 80 는 scanf ( " %의 D ' , N); 81 // 输入并准备离散 82 INT의 CB = 1 ; 83 B [ 0 ] = - 1 ; (84) 에 대한이 ( 값 int = 1을 0 ; i가 ++] i가 N < ) 85 { 86 (scanf와 " % d 개 %의 D를 " & A [I] 펜닐, & A [i]를 .R); 87 B [CB가 ++] = A [i]를 .L; 88 B [CB가 ++] = A [i]를 .R; 89 } 90 // 이산 (91)이 정렬 (B의 + 1. , B + CB) 92 CD = 0 , 93 대 ( INT I = 1. , I는 CB <; I는 ++ ) 94 IF (! B [I]가 = B [I- . 1 ]) 95 D [CD ++] = B [I]가, 96 // 기여 길이 CD에 따라 이산화 97 빌드 ( 1. , 1. , CD) 98 // 세그먼트 트리 업데이트 (99) 에 대해 ( int로 I = 0 ; I <N-; I는 ++ ) (100) 업데이트 ( . 1 , getId (A [I] .L) getId가 (A [I]는 .R), I는 + 1. ) 101 CNT를 = 1. , 102 추 [ 0 ] = - 1. , 103 // 단부에 푸시 할 모든 푸시 다운 유닛 (104) 쿼리 ( 1이다. ) (105) // 요청 ANS 106 정렬 (추 + 1. 추 + CNT) (107) INT ANS = 0 ; 108 대 ( INT I = 1. ; I <CNT; I는 ++ ) 109 IF (추 [I]! 추 = I- . 1]) 110 ANS ++ ; 111 // 출력 112 의 printf ( " % D의 \의 N- " , ANS) 113 } 114 복귀 0 , 115 }