差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
次のリビジョン両方とも次のリビジョン
programming_algorithm:data_structure:binary_indexed_tree [2019/06/17] ikatakosprogramming_algorithm:data_structure:binary_indexed_tree [2019/11/07] ikatakos
行 1: 行 1:
 ======Binary Indexed Tree====== ======Binary Indexed Tree======
 +
 +=====概要=====
  
 [[http://hos.ac/slides/20140319_bit.pdf|Binary Indexed Tree のはなし - hos.ac]][pdf] [[http://hos.ac/slides/20140319_bit.pdf|Binary Indexed Tree のはなし - hos.ac]][pdf]
行 13: 行 15:
  
 これだけ見ると「そんなのが何の役に立つの?」って感じだが、頭のいい人だと全然関係ないように見える問題を変換して効率的に解いたりしちゃうらしい。 これだけ見ると「そんなのが何の役に立つの?」って感じだが、頭のいい人だと全然関係ないように見える問題を変換して効率的に解いたりしちゃうらしい。
 +
 +=====実装=====
  
 詳しい説明は上のpdfで懇切丁寧に行われているので、Pythonコードだけメモ。 詳しい説明は上のpdfで懇切丁寧に行われているので、Pythonコードだけメモ。
行 98: 行 102:
  
  
 +=====区間の最大値・最小値=====
 +
 +Segment Treeほどの柔軟性は無いが、いくらかの制約された条件下で、区間最大値・最小値の管理にも使える(以下は最大値の例)
 +
 +  * $update(i, x)$: $a_i$ を $x$ で更新する。この際、$x$ は必ず元の $a_i$ 以上でなければならない
 +  * $getmax(i)$: $a_1~a_i$ の最大値を取得する。必ず1からの最大値であり、途中からの $a_s~a_t$ は取得できない。
 +
 +単純に、上記のコードの加算を、MAXを取る操作に置きかえればよい。
 +
 +<sxh python>
 +class Bit:
 +    def __init__(self, n):
 +        self.size = n
 +        self.tree = [0] * (n + 1)
 +
 +    def sum(self, i):
 +        s = -(10 ** 18)  # -INF
 +        while i > 0:
 +            s = max(s, self.tree[i])
 +            i -= i & -i
 +        return s
 +
 +    def add(self, i, x):
 +        while i <= self.size:
 +            self.tree[i] = max(x, self.tree[i])
 +            i += i & -i
 +
 +</sxh>
 +
 +少し理解は難しくなるが、BITを2本使って管理することで、上記の制約を無くした区間最大値・最小値も得られる。
 +
 +  * [[https://ioinformatics.org/journal/v9_2015_39_44.pdf]]
 +  * [[https://freestylewiki.xyz/fswiki/wiki.cgi?page=%E3%83%95%E3%82%A7%E3%83%8B%E3%83%83%E3%82%AF%E6%9C%A8%28Binary+Indexed+Tree%29#p12|フェニック木(Binary Indexed Tree) - FreeStyleWiki]]
 +
 +====累積和のlower bound====
 +
 +累積和が $x$ のindexや、$x$ を越えない最大のindexとその時の累積和を得ることができる。
 +
 +  * [[https://codeforces.com/blog/entry/61364|[Tutorial] Searching Binary Indexed Tree in O(log(N)) using Binary Lifting - Codeforces]]
 +
 +<sxh python>
 +class Bit:
 +    def __init__(self, n): (略)
 +    def sum(self, i): (略)
 +    def add(self, i, x): (略)
 +
 +    def lower_bound(self, x):
 +        """ xを越えない最大のindexとその累積和 """
 +        sum = 0
 +        pos = 0
 +        for i in range(self.depth, -1, -1):
 +            k = pos + (1 << i)
 +            if k <= self.size and sum + self.tree[k] < x:
 +                sum += self.tree[k]
 +                pos += 1 << i
 +        return pos + 1, sum
 +</sxh>
  
programming_algorithm/data_structure/binary_indexed_tree.txt · 最終更新: 2023/02/08 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0