다음 N개 줄에는 매일 매일 심은 식물의 두 줄기 좌표 L과 R이 주어진다. (1 ≤ L < R ≤ 100,000)
출력
총 N개의 줄에 매일 매일 핀 꽃의 수를 출력한다.
입력 예시
4
1 4
3 7
1 6
2 6
출력 예시
0
1
1
2
풀이
n번째의 구간 [L, R]의 식물이 심어진다고 가정하자. 그렇다면 꽃이 필 수 있는 경우는 L, R의 수직선이 각각 이전에 그어진 수평선 중 아직 쓰이지 않은 수평선과 만날 때이다. 즉
search(x) : x에 저장된, 아직 만나지 않은 수평선의 개수을 출력. 그 후 모든 만나지 않은 직선을 만난 셈이므로 0으로 초기화
update(l, r) : l, r구간에 수평선이 지나므로 l, r구간에 1을 추가
두 가지 기능을 수행한다고 볼 수 있다. 구간 [L, R]의 경우 (search(L) + search(R)값을 출력하고, 동시에 update(L+1, R-1)로 업데이트해줄 필요가 있다. 구간 업데이트를 O(logN)으로 수행 가능한 lazy segment tree를 사용해봄직하다.
풀이 코드
import sys
input = sys.stdin.readline
MAX = 10**5
N = int(input())
tree = [0]*(4*MAX+4)
lazy = [0]*(4*MAX+4)
def propagate(start, end, idx) :
if start != end :
lazy[idx*2] += lazy[idx]
lazy[idx*2+1] += lazy[idx]
else :
tree[idx] += lazy[idx]
lazy[idx] = 0
def update(l, r, start=0, end=MAX, idx=1) :
if l > r :
return
propagate(start, end, idx)
if l > end or r < start :
return
if l <= start <= end <= r :
lazy[idx] += 1
propagate(start, end, idx)
return
mid = (start + end) // 2
update(l, r, start, mid, idx*2)
update(l, r, mid+1, end, idx*2+1)
def search(target) :
start, end, idx = 0, MAX, 1
while start < end :
propagate(start, end, idx)
mid = (start + end) // 2
if target <= mid :
end = mid
idx = idx*2
else :
start = mid+1
idx = idx*2+1
propagate(start, end, idx)
result = tree[idx]
tree[idx] = 0
return result
for _ in range(N) :
L, R = map(int, input().split())
print(search(L) + search(R))
update(L+1, R-1)