线段树
很多人都知道线段树的强大,也知道他是个什么样的结构,但一到用代码实现是不是就懵了!线段树模板其实就是个代码比较长,但代码重复很多的一个递归!
线段树用途:
数字之和——总数字之和 = 左区间数字之和 + 右区间数字之和
最大公因数(GCD)——总GCD = gcd( 左区间GCD , 右区间GCD );
最大值——总最大值=max(左区间最大值,右区间最大值)
下标从0开始的线段树
#include<bits/stdc++.h>
using namespace std;
const int MAX=1000;
int arr[MAX],tree[MAX]={0};
void pf(){
for(int i=0;i<=16;i++){
printf("tree[%d]=%d",i,tree[i]);
cout << endl ;
}
cout << endl;
}
void build_tree(int arr[],int tree[],int node,int st,int ed){
if(st>=ed){
tree[node]=arr[st];
return;
}
int mid=(st+ed)>>1;
int left_node=2*node+1;
int right_node=2*node+2;
build_tree(arr,tree,left_node,st,mid);
build_tree(arr,tree,right_node,mid+1,ed);
tree[node]=tree[left_node]+tree[right_node];
}
void update_tree(int arr[],int tree[],int node,int st,int ed,int idx,int val){
if(st==ed){
arr[idx]=val;
tree[node]=val;
return;
}
int mid=(st+ed)>>1;
int left_node=node*2+1;
int right_node=node*2+2;
if(idx>=st&&idx<=mid) update_tree(arr,tree,left_node,st,mid,idx,val);
else update_tree(arr,tree,right_node,mid+1,ed,idx,val);
tree[node]=tree[left_node]+tree[right_node];
}
int query_tree(int arr[],int tree[],int node,int st,int ed,int L,int R){
if(L>ed||R<st) return 0;
else if(st==ed) return tree[node];
int mid=(st+ed)>>1;
int left_node=node*2+1;
int right_node=node*2+2;
int sum_left=query_tree(arr,tree,left_node,st,mid,L,R);
int sum_right=query_tree(arr,tree,right_node,mid+1,ed,L,R);
int Max=max(sum_left,sum_right);
Max=max(Max,sum_left+sum_right);
return Max;
}
int main(){
int n;
cin >> n;
for(int i=0;i<n;i++) cin >> arr[i];
build_tree(arr,tree,0,0,n-1);
pf();
return 0;
}