새소식

Algorithm

인덱스 트리

  • -

C++

#include <cstdio>
#include <cstring>

#define MINIMUM_POWER_OF_2_GREATER_THAN_MAXIMUM_N 131072

int T[MINIMUM_POWER_OF_2_GREATER_THAN_MAXIMUM_N*2];
int M = 1;

void init(int N) {
    while (M < N) {
        M *= 2;
    }
}

void update(int index, int delta) {
    index = M + index - 1;
    while (index > 0) {
        T[index] += delta;
        index /= 2;
    }
}

int sum(int left, int right) {
    left = left + M - 1; right = right + M - 1;
    int sum = 0;
    while (left <= right) {
        if ((left & 1) == 1) sum += T[left++];
        if ((right & 1) == 0) sum += T[right--];
        left /= 2;
        right /= 2;
    }
    return sum;
}

Swift

import Foundation

struct IndexedTree<Element> {
  private var storage: Array<Element?>
  private var capacity: Int
  private var operation: (Element?, Element?) -> Element?
  private var firstLeafIndex: Int
  private var size: Int = 0

  init(capacity: Int, elements: [Element], operation: @escaping (Element, Element) -> Element) {
    self.capacity = capacity
    self.operation = { lhs, rhs in
      if let lhs = lhs, let rhs = rhs {
        return operation(lhs, rhs)
      } else if let lhs = lhs {
        return lhs
      } else if let rhs = rhs {
        return rhs
      } else {
        return nil
      }
    }
    firstLeafIndex = 1
    while firstLeafIndex < capacity {
      firstLeafIndex *= 2
    }
    storage = Array<Element?>(repeating: nil, count: firstLeafIndex * 2)
    elements.map { add($0) }
  }
  
  private mutating func add(_ element: Element) {
    var index = size + firstLeafIndex
    while index > 0 {
      print(index)
      storage[index] = operation(storage[index], element)
      index /= 2
    }
    size += 1
  }
  
  func idealValue(_ lowerBound: Int, _ upperBound: Int) -> Element? {
    guard 0 <= lowerBound, upperBound < size else { return nil }
    var lower = lowerBound + firstLeafIndex
    var upper = upperBound + firstLeafIndex
    var idealValue: Element?
    while lower < upper {
      if (lower & 1) == 1, let lowerValue = storage[lower] {
        idealValue = operation(idealValue, lowerValue)
        lower += 1
      }
      if (upper & 1) == 0, let upperValue = storage[upper] {
        idealValue = operation(idealValue, upperValue)
        upper -= 1
      }
      lower /= 2
      upper /= 2
    }
    if lower == upper, let lowerValue = storage[lower] {
      idealValue = operation(idealValue, lowerValue)
    }
    return idealValue
  }
}
반응형

'Algorithm' 카테고리의 다른 글

다익스트라  (0) 2019.06.20
최소 스패닝 트리  (0) 2019.06.20
스택, 큐, 데큐, 힙  (0) 2019.06.20
빠른 입출력  (0) 2019.06.20
복잡도 계산  (0) 2019.06.20
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.