线段树+树状数组
线段树
有一段长度为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();
}
}

浙公网安备 33010602011771号