线段树
对一个数组,如果要同时进行多次求区间和操作,修改元素操作。怎样能使时间复杂度降到最低?线段树为我们解决了这样一个问题。
#include<iostream> #include<algorithm> #include<vector> #include<string> using namespace std; const int N=1010; int tree[N],arr[N]; //建立一颗完全二叉树 void build_tree(int arr[], int tree[], int node, int st, int ed){ if(st==ed){ tree[node]=arr[st]; }else{ int mid=st+ed>>1; int l_node=2*node+1; int r_node=2*node+2; build_tree(arr,tree,l_node, st, mid); build_tree(arr,tree,r_node,mid+1,ed); tree[node]=tree[l_node]+tree[r_node]; } } //更新数组中某一个下标的值 void update_arr(int arr[], int tree[], int node, int st, int ed, int idx, int val){ if(st==ed){ arr[idx]=val; tree[node]=val; }else{ int mid=st+ed>>1; int l_node=2*node+1; int r_node=2*node+2; if(idx>=st&&idx<=mid){ update_arr(arr,tree,l_node,st,mid,idx,val); }else{ update_arr(arr,tree,r_node,mid+1,ed,idx,val); } tree[node]=tree[l_node]+tree[r_node]; } } //计算arr中区间[L,R]的和 int query_arr(int arr[], int tree[],int node, int st, int ed, int L, int R){ if(R<st||L>ed){ return 0; }else if(L<=st&&ed<<R){ return tree[node]; }else if(st==ed){ return tree[node]; }else{ int mid=st+ed>>1; int l_node=2*node+1; int r_node=2*node+2; int sum_l=query_arr(arr,tree,l_node,st,mid,L,R); int sum_r=query_arr(arr,tree,r_node,mid+1,ed,L,R); return sum_l+sum_r; } } int main(void){ int n; cin>>n; for(int i=0;i<n;i++)cin>>arr[i]; build_tree(arr,tree,0,0,n-1); for(int i=0;i<15;i++)cout<<tree[i]<<' '; update_arr(arr,tree,0,0,n-1,4,6);//修改a[4]=6; cout<<tree[0]<<endl; return 0; }