AlgoStruct/Data Structure

์ž๋ฃŒ๊ตฌ์กฐ, ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ(Segment Tree) [Python]

Winterrat 2023. 8. 17. 23:55

๐Ÿฆ• ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ(Segment Tree)๋ž€?

์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋Š” ๋ฐฐ์—ด์—์„œ ํŠน์ • ๊ตฌ๊ฐ„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฟผ๋ฆฌํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ด์ง„ ํŠธ๋ฆฌ ๊ธฐ๋ฐ˜์˜ ์ž๋ฃŒ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ์ด ์ž๋ฃŒ๊ตฌ์กฐ๋Š” ์ฃผ๋กœ ๋ฒ”์œ„ ์ฟผ๋ฆฌ ๋ฌธ์ œ์— ํ™œ์šฉ๋˜๋ฉฐ, ๊ทธ ์ค‘์—์„œ๋„ ๊ตฌ๊ฐ„ ํ•ฉ์„ ๋น ๋ฅด๊ฒŒ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐ์— ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์›๋ฆฌ
์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ๊ฐ ๋…ธ๋“œ๋Š” ๋ฐฐ์—ด์˜ ํŠน์ • ๊ตฌ๊ฐ„์„ ๋Œ€ํ‘œํ•ฉ๋‹ˆ๋‹ค.
๋ฆฌํ”„ ๋…ธ๋“œ๋Š” ๋ฐฐ์—ด์˜ ๊ฐœ๋ณ„ ์›์†Œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
๋ถ€๋ชจ ๋…ธ๋“œ๋Š” ์ž์‹ ๋…ธ๋“œ๋“ค์˜ ํ•ฉ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋Š” ๋ฐฐ์—ด ์ „์ฒด์˜ ํ•ฉ์„ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ
๋ฐฐ์—ด A [1, 3, 5, 7, 9, 11]์„ ๊ณ ๋ คํ•ด๋ด…์‹œ๋‹ค.
์ด๋•Œ Tree ๋Š” [0, 36, 9, 27, 4, 5, 16, 11, 1, 3, 7, 9] ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๊ฐ ๋…ธ๋“œ์—๋Š” ๋ฐฐ์—ด์˜ ๊ตฌ๊ฐ„ ํ•ฉ์ด ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฆฌํ”„ ๋…ธ๋“œ์—๋Š” ์ฃผ์–ด์ง„ ๋ฐฐ์—ด(A) ๊ฐ’๋“ค์ด ์ €์žฅ๋˜๊ณ  ๋‚ด๋ถ€ ๋…ธ๋“œ์—๋Š” ์ž์‹ ๋…ธ๋“œ์˜ ํ•ฉ์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.



๋ฃจํŠธ ๋…ธ๋“œ(36)๋Š” ์ „์ฒด ๋ฐฐ์—ด์˜ ํ•ฉ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
์ขŒ์ธก ์ž์‹ ๋…ธ๋“œ(9)๋Š” ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ๋ถ€ํ„ฐ ์„ธ ๋ฒˆ์งธ ์›์†Œ๊นŒ์ง€์˜ ํ•ฉ(A[0:2])์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
์šฐ์ธก ์ž์‹ ๋…ธ๋“œ(27)๋Š” ๋ฐฐ์—ด์˜ ๋„ค ๋ฒˆ์งธ๋ถ€ํ„ฐ ์—ฌ์„ฏ ๋ฒˆ์งธ ์›์†Œ๊นŒ์ง€์˜ ํ•ฉ(A[3:5])์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
์ด์™€ ๊ฐ™์ด ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋Š” ๊ตฌ๊ฐ„์˜ ํ•ฉ์„ ๋น ๋ฅด๊ฒŒ ๊ณ„์‚ฐํ•˜๊ฑฐ๋‚˜, ๋ฐฐ์—ด์˜ ํŠน์ • ์›์†Œ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋„ O(logN) ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ตฌ๊ฐ„์˜ ํ•ฉ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.



๐Ÿ‘ˆ๐Ÿฟ ํŒŒ์ด์ฌ ์ฝ”๋“œ ๊ตฌํ˜„

1. init ๋ฉ”์†Œ๋“œ

def __init__(self, arr):
    # ๋ฐฐ์—ด์˜ ๊ธธ์ด
    self.n = len(arr)
    # ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ์‚ฌ์ด์ฆˆ๋Š” ์›๋ž˜ ๋ฐฐ์—ด์˜ 4๋ฐฐ๋กœ ์„ค์ • (์ถฉ๋ถ„ํ•œ ๊ณต๊ฐ„ ํ™•๋ณด)
    self.tree = [0] * (4 * self.n)
    # ํŠธ๋ฆฌ ๋นŒ๋“œ
    self.build(0, self.n-1, 1, arr)
  1. self.n = len(arr):
    ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์˜ ๊ธธ์ด๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‚˜์ค‘์— ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ๋ฒ”์œ„๋ฅผ ์ •ํ•  ๋•Œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  2. self.tree = [0] * (4 * self.n):
    ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ํฌ๊ธฐ๋Š” ์›๋ž˜ ๋ฐฐ์—ด์˜ ๊ธธ์ด์˜ 4๋ฐฐ๊ฐ€ ๋˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋Š” ์ด์œ ๋Š” ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๊ฐ€ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ด๋ฅผ ๋ฐฐ์—ด๋กœ ํ‘œํ˜„ํ•  ๋•Œ ์ถฉ๋ถ„ํ•œ ๊ณต๊ฐ„์„ ํ™•๋ณดํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.
  3. self.build(0, self.n-1, 1, arr):
    ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, ์ „์ฒด ๋ฐฐ์—ด์˜ ๋ฒ”์œ„์ธ 0๋ถ€ํ„ฐ self.n-1๊นŒ์ง€๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋ฉฐ, ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋Š” 1์ด๋ผ๋Š” ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

2. build ๋ฉ”์†Œ๋“œ

build ๋ฉ”์†Œ๋“œ๋Š” ์ดˆ๊ธฐ ๋ฐฐ์—ด์„ ๋ฐ›์•„ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.

๋ถ„ํ•  ์ •๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

def build(self, start, end, node, arr):
    # ๋ฆฌํ”„ ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ ๋ฐฐ์—ด์˜ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋Œ€์ž…
    if start == end:
        self.tree[node] = arr[start]
        return self.tree[node]
    # ๊ตฌ๊ฐ„์„ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„์–ด ์žฌ๊ท€์ ์œผ๋กœ ํŠธ๋ฆฌ ์ƒ์„ฑ
    mid = (start + end) // 2
    self.tree[node] = self.build(start, mid, node*2, arr) + self.build(mid+1, end, node*2+1, arr)
    return self.tree[node]
  • start, end๋Š” ํ˜„์žฌ ๊ตฌ๊ฐ„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ฒ˜์Œ ํ˜ธ์ถœ ์‹œ ์ „์ฒด ๋ฐฐ์—ด ๋ฒ”์œ„๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • node๋Š” ํ˜„์žฌ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์—์„œ์˜ ์œ„์น˜ (๋…ธ๋“œ ๋ฒˆํ˜ธ)๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋™์ž‘๋ฐฉ์‹

  1. ๋งŒ์•ฝ start์™€ end๊ฐ€ ๋™์ผํ•˜๋ฉด (์ฆ‰, ๋ฆฌํ”„ ๋…ธ๋“œ์— ๋„๋‹ฌํ–ˆ๋‹ค๋ฉด) ํ•ด๋‹น ๋…ธ๋“œ์— ๋ฐฐ์—ด์˜ ํ•ด๋‹น ์ธ๋ฑ์Šค ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ํ˜„์žฌ ๊ตฌ๊ฐ„์„ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ์žฌ๊ท€์ ์œผ๋กœ ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.
  3. ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’์„, ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ์™€ ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ์˜ ํ•ฉ์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

3. query ๋ฉ”์†Œ๋“œ

query ๋ฉ”์†Œ๋“œ๋Š” ์ง€์ •๋œ ๊ตฌ๊ฐ„์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

def query(self, left, right, node, node_left, node_right):
    # ๊ตฌ๊ฐ„์ด ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
    if right < node_left or node_right < left:
        return 0
    # ํ˜„์žฌ ๋…ธ๋“œ ๊ตฌ๊ฐ„์ด ์ฟผ๋ฆฌ ๊ตฌ๊ฐ„์— ์™„์ „ํžˆ ํฌํ•จ๋  ๊ฒฝ์šฐ
    if left <= node_left and node_right <= right:
        return self.tree[node]
    # ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์–ด ํ•ฉ์„ ๊ณ„์‚ฐ
    mid = (node_left + node_right) // 2
    return self.query(left, right, node*2, node_left, mid) + self.query(left, right, node*2+1, mid+1, node_right)

query ๋ฉ”์†Œ๋“œ๋Š” ์ง€์ •๋œ ๊ตฌ๊ฐ„์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

  • left, right๋Š” ๊ตฌ๊ฐ„ ํ•ฉ์„ ๊ตฌํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.
  • node_left, node_right๋Š” ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ ์ปค๋ฒ„ํ•˜๋Š” ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.

๋™์ž‘ ๋ฐฉ์‹

  1. ๋งŒ์•ฝ ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฒ”์œ„์™€ ์š”์ฒญ๋œ ๋ฒ”์œ„๊ฐ€ ๊ฒน์น˜์ง€ ์•Š์œผ๋ฉด, 0์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  2. ์š”์ฒญ๋œ ๋ฒ”์œ„๊ฐ€ ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฒ”์œ„์— ์™„์ „ํžˆ ํฌํ•จ๋œ๋‹ค๋ฉด, ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์š”์ฒญ๋œ ๋ฒ”์œ„๋ฅผ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์–ด ์žฌ๊ท€์ ์œผ๋กœ ํ•ฉ์„ ๊ณ„์‚ฐํ•˜๊ณ , ๋‘ ๊ฒฐ๊ณผ๋ฅผ ํ•ฉ์ณ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

4. update ๋ฉ”์†Œ๋“œ

update ๋ฉ”์†Œ๋“œ๋Š” ๋ฐฐ์—ด์˜ ํŠน์ • ์›์†Œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ , ์ด์— ๋”ฐ๋ผ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.

    def update(self, index, new_value, node, node_left, node_right):
        # ๊ตฌ๊ฐ„ ๋ฐ–์ธ ๊ฒฝ์šฐ
        if index < node_left or node_right < index:
            return self.tree[node]
        # ๋ฆฌํ”„ ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ ๊ฐ’์„ ๊ฐฑ์‹ 
        if node_left == node_right:
            self.tree[node] = new_value
            return self.tree[node]
        # ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ์ž์‹ ๋…ธ๋“œ๋“ค๋„ ๊ฐฑ์‹ ํ•ด์•ผ ํ•จ
        mid = (node_left + node_right) // 2
        self.tree[node] = self.update(index, new_value, node*2, node_left, mid) + self.update(index, new_value, node*2+1, mid+1, node_right)
        return self.tree[node]
  • index๋Š” ๊ฐฑ์‹ ํ•˜๋ ค๋Š” ์›์†Œ์˜ ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • new_value๋Š” ๊ฐฑ์‹ ํ•˜๋ ค๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค.

๋™์ž‘ ๋ฐฉ์‹

  1. ๋งŒ์•ฝ ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ฒ”์œ„๊ฐ€ ๊ฐฑ์‹ ํ•˜๋ ค๋Š” ์›์†Œ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์œผ๋ฉด, ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋งŒ์•ฝ ๋ฆฌํ”„ ๋…ธ๋“œ์— ๋„๋‹ฌํ–ˆ๋‹ค๋ฉด, ์›์†Œ์˜ ๊ฐ’์„ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ํ•ด๋‹น ์›์†Œ๋ฅผ ํฌํ•จํ•˜๋Š” ์ž์‹ ๋…ธ๋“œ๋“ค์„ ์žฌ๊ท€์ ์œผ๋กœ ๊ฐฑ์‹ ํ•˜๊ณ , ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’์„ ์ž์‹ ๋…ธ๋“œ๋“ค์˜ ํ•ฉ์œผ๋กœ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.

5. ์ „์ฒด ์ฝ”๋“œ

class SegmentTree:
    def __init__(self, arr):
        # ๋ฐฐ์—ด์˜ ๊ธธ์ด
        self.n = len(arr)
        # ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ์‚ฌ์ด์ฆˆ๋Š” ์›๋ž˜ ๋ฐฐ์—ด์˜ 4๋ฐฐ๋กœ ์„ค์ • (์ถฉ๋ถ„ํ•œ ๊ณต๊ฐ„ ํ™•๋ณด)
        self.tree = [0] * (4 * self.n)
        # ํŠธ๋ฆฌ ๋นŒ๋“œ
        self.build(0, self.n-1, 1, arr)

    # ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ ๋นŒ๋“œ ํ•จ์ˆ˜
    def build(self, start, end, node, arr):
        # ๋ฆฌํ”„ ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ ๋ฐฐ์—ด์˜ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋Œ€์ž…
        if start == end:
            self.tree[node] = arr[start]
            return self.tree[node]
        # ๊ตฌ๊ฐ„์„ ์ ˆ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ„์–ด ์žฌ๊ท€์ ์œผ๋กœ ํŠธ๋ฆฌ ์ƒ์„ฑ
        mid = (start + end) // 2
        self.tree[node] = self.build(start, mid, node*2, arr) + self.build(mid+1, end, node*2+1, arr)
        return self.tree[node]

    # ๊ตฌ๊ฐ„ ํ•ฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜
    def query(self, left, right, node, node_left, node_right):
        # ๊ตฌ๊ฐ„์ด ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
        if right < node_left or node_right < left:
            return 0
        # ํ˜„์žฌ ๋…ธ๋“œ ๊ตฌ๊ฐ„์ด ์ฟผ๋ฆฌ ๊ตฌ๊ฐ„์— ์™„์ „ํžˆ ํฌํ•จ๋  ๊ฒฝ์šฐ
        if left <= node_left and node_right <= right:
            return self.tree[node]
        # ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์–ด ํ•ฉ์„ ๊ณ„์‚ฐ
        mid = (node_left + node_right) // 2
        return self.query(left, right, node*2, node_left, mid) + self.query(left, right, node*2+1, mid+1, node_right)

    # ๋ฐฐ์—ด์˜ ํŠน์ • ์›์†Œ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ํ•จ์ˆ˜
    def update(self, index, new_value, node, node_left, node_right):
        # ๊ตฌ๊ฐ„ ๋ฐ–์ธ ๊ฒฝ์šฐ
        if index < node_left or node_right < index:
            return self.tree[node]
        # ๋ฆฌํ”„ ๋…ธ๋“œ์ธ ๊ฒฝ์šฐ ๊ฐ’์„ ๊ฐฑ์‹ 
        if node_left == node_right:
            self.tree[node] = new_value
            return self.tree[node]
        # ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ์ž์‹ ๋…ธ๋“œ๋“ค๋„ ๊ฐฑ์‹ ํ•ด์•ผ ํ•จ
        mid = (node_left + node_right) // 2
        self.tree[node] = self.update(index, new_value, node*2, node_left, mid) + self.update(index, new_value, node*2+1, mid+1, node_right)
        return self.tree[node]

# arr์˜ ๊ฐ’ ์„ค์ •
A = [1, 3, 5, 7, 9, 11]
seg_tree = SegmentTree(A)

# ์˜ˆ์‹œ ์ฟผ๋ฆฌ ๋ฐ ์ถœ๋ ฅ
print(seg_tree.query(1, 3, 1, 0, seg_tree.n-1))  # 1~3 ์ธ๋ฑ์Šค ๊ตฌ๊ฐ„ ํ•ฉ
# ๊ฐ’ ๋ณ€๊ฒฝ ์˜ˆ์‹œ: arr์˜ 2๋ฒˆ์งธ ์›์†Œ๋ฅผ 10์œผ๋กœ ๋ณ€๊ฒฝ
seg_tree.update(2, 10, 1, 0, seg_tree.n-1)
print(seg_tree.query(1, 3, 1, 0, seg_tree.n-1))  # 1~3 ์ธ๋ฑ์Šค ๊ตฌ๊ฐ„ ํ•ฉ ์ถœ๋ ฅ
A = [1, 3, 5, 7, 9, 11]
15 [3, 5, 7]

A = [1, 3, 10, 7, 9, 11]
20 [3, 10, 7]