线段树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include<iostream>
#include<vector>
#include<cstring>
#include<cassert>
using namespace std;
template <typename E>
class SegmentTree{
private:
E *tree;
E *data;
int size;

//建立线段树
void buildSegmentTree(int treeIndex,int l,int r){
if(l==r){
tree[treeIndex]=data[l];
return ;
}
int leftIndex=leftChild(treeIndex);
int rightIndex=rightChild(treeIndex);

int mid=l+(r-l)/2;
buildSegmentTree(leftIndex,l,mid);
buildSegmentTree(rightIndex,mid+1,r);
tree[treeIndex]=tree[leftIndex]+tree[rightIndex];
}

//左孩子节点索引
int leftChild(int index){
return index*2+1;
}

//右孩子节点索引
int rightChild(int index){
return index*2+2;
}

//查询queryl到queryr线段元素的和
E query(int treeIndex,int l,int r,int queryl,int queryr){

if(l==queryl&&r==queryr)
return tree[treeIndex];
int mid=l+(r-l)/2;
int leftIndex=leftChild(treeIndex);
int rightIndex=rightChild(treeIndex);
if(queryl>=mid+1)
return query(rightIndex,mid+1,r,queryl,queryr);
else if(queryr<=mid)
return query(leftIndex,l,mid,queryl,queryr);

E leftresult=query(leftIndex,l,mid,queryl,mid);
E rightresult=query(rightIndex,mid+1,r,mid+1,queryr);

return leftresult+rightresult;

}

void set(int treeIndex,int l,int r,int index,E e){
if(l==r)
tree[treeIndex]=e;
int mid=l+(r-l)/2;
int leftIndex=leftChild(treeIndex);
int righIndex=rightChild(treeIndex);
if(mid<index)
set(righIndex,mid+1,r,index,e);
if(mid>=index)
set(leftIndex,l,mid,index,e);
tree[treeIndex]=tree[leftIndex]+tree[righIndex];
}
public:
SegmentTree(E arr[],int n){
this->data=new E[n];
for(int i=0;i<n;i++)
data[i]=arr[i];
this->tree=new E[4*n];
this->size=n;
buildSegmentTree(0,0,n-1);
}

int getSize(){
return this->size;
}

E get(int index){
if(index<0||index>=size){
cout<<"Error"<<endl;
return NULL;
}
return data[index];
}

E query(int queryl,int queryr){
if(queryl<0||queryl>=size||queryr<0||queryr>=size){
cout<<"Error"<<endl;
return NULL;
}
return query(0,0,size-1,queryl,queryr);
}

void set(int index,E e){
if(index<0||index>=size){
cout<<"Error"<<endl;
return ;
}
data[index]=e;
set(0,0,size-1,index,e);
}
};