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 |