import sys
import math
def init():
global tree_size
for i in range(tree_size-1,0,-1):
segement_tree[i] = segement_tree[i*2] + segement_tree[i*2+1]
def update(index,diff):
while index >= 1:
segement_tree[index] += diff
index//=2
def sum_range(node_number,start,end,left,right):
if left > end or start > right:
return 0
if (left <= start) and (end <= right):
return segement_tree[node_number]
return sum_range(node_number*2,start,(start+end)//2,left,right) + sum_range(node_number*2+1,(start+end)//2+1,end,left,right)
input = sys.stdin.readline
N,M = map(int,input().split())
height = math.ceil(math.log2(N))
tree_size = 2**height
total_size = 2**(height+1)
segement_tree = [0]*total_size
for i in range(N):
segement_tree[tree_size + i] = 0
init()
for i in range(M):
command = list(map(int,input().split()))
if command[0] == 1:
diff = command[2] - segement_tree[tree_size + command[1] - 1]
update(command[1]+tree_size-1,diff)
else:
if command[1] > command[2]:
command[1],command[2] = command[2],command[1]
print(sum_range(1,0,tree_size-1,command[1]-1,command[2]-1))
세그먼트 트리를 이용해서 풀어야했던 문제이다.
여전히 세그먼트 트리는 정확히 잘 모르겠다는게 함정이지만, 예전에 만들어뒀던 세그먼트 트리에서 일부분만 고쳤다.
구간의 값을 특정위치에 미리 저장을 해놓고, 어떤 위치의 값이 변했을때, 그 값이 포함된 구간들을 갱신하는 것인데,
아직 세그먼트 트리는 어려운 것같다.
세그먼트 트리를 짜놓은 코드를 이용해서, 풀라면 풀수 있을것 같지만, 실전에서 노베이스부터 설계를 하라고 하면
너무 어려울 것 같다.
import sys
input = sys.stdin.readline
def init(N):
for i in range(N-1,0,-1):
tree[i] = tree[i<<1] + tree[i<<1|1]
def query(left,right,N):
ans = 0
left = left +N
right = right +N
while left<right:
if (left&1):
ans += tree[left]
left += 1
if (right&1):
right -= 1
ans += tree[right]
left >>= 1
right>>= 1
return ans
def update(pos,val,N):
tree[pos+N] = val
pos = pos +N
while pos > 1:
tree[pos>>1] = tree[pos] + tree[pos^1]
pos >>= 1
N,M = map(int,input().split())
tree = [0]*(3*N)
for _ in range(M):
command = list(map(int,input().split()))
if command[0] == 1:
update(command[1],command[2],N)
else:
if command[1] > command[2]:
command[1],command[2] = command[2],command[1]
sys.stdout.write(str(query(command[1],command[2]+1,N))+'\n')
이 코드는 https://blog.joonas.io/129 에 있는 비재귀 세그먼트 트리를 설명한 글을 이용해서 푼 문제이다.
여전히 어렵다.
업데이트가 빈번하고, 특정값을 구할때, 트리를 이용한 풀이들이 많은데, 아직 트리에 대해 정확히 알지 못해서
그런지 많이 어렵다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 10159 저울 (0) | 2021.05.27 |
---|---|
[BOJ/백준] 1644 소수의 연속합 (0) | 2021.05.27 |
[BOJ/백준] 1368 물대기 (0) | 2021.05.23 |
[BOJ/백준] 10775 공항 (0) | 2021.05.22 |
[BOJ/백준] 11779 최소 비용 구하기 2 (0) | 2021.05.19 |