线段树+树状数组

线段树
有一段长度为i的数组[0,i-1],我们要求实现一下功能
1.修改其中任意元素,通过下标修改元素,复杂度O(1).
2.求任意一端数组的和

  • 方法一 遍历
  • 复杂度 O(n)
  • 方法二 线段树
  • 复杂度 O(logn)

什么是线段树
一种按二叉树存储的数据结构,每个节点存储的一段数据的总和。

interface Merger<E>{
   E merge(E a,E b);
}
class SegmentTree<E>{
   E[] tree;
   E[] data;
   Merger<E> merger;
  public SegmentTree(E[] arr,Merger<E> merge){
      this.merger=merge;
      data=(E[]) new Object[arr.length];
      for(int i=0;i<arr.length;i++){
          data[i]=arr[i];
      }
      tree=(E[]) new Object[4*arr.length];
      build(0,0,data.length-1);
  }
   public void build(int index,int l,int r){
       if(l==r){
        tree[index]=data[l];   
           return;
       }
       int lIndex=2*index+1;
       int rIndex=lIndex+1;
       build(lIndex, l, l+(r-l)/2);
       build(rIndex,l+(r-l)/2+1,r);
       tree[index]=merger.merge(tree[lIndex],tree[rIndex]);
   }
   @Override
   public String toString() {
       StringBuilder res = new StringBuilder();
       res.append('[');
       for (int i = 0; i < tree.length; i++) {
           if (tree[i] != null) {
               res.append(tree[i]);
           } else {
               res.append("null");
           }

           if( i != tree.length-1){
               res.append(", ");
           }
       }
       res.append(']');
       return res.toString();
   }
}
posted @ 2020-07-11 14:50  Kotonoha  阅读(193)  评论(0)    收藏  举报