線段樹——區間求和
阿新 • • 發佈:2022-06-06
#include <bits/stdc++.h> using namespace std; //以下是線段樹的模板,讓區間查詢和修改的時間複雜度到O(lgn); class XianDuanTree{ private: vector<int> arr; vector<int> tree; public: XianDuanTree(vector<int> &arr){ this->arr = arr; } //建樹,根據vector<int> arr;構建區間查詢樹vector<int>tree//start,end限定區間範圍,node_index是這個結點在tree的索引; void build_tree(vector<int> &arr,vector<int> &tree,int start,int end,int node_index ){ //只有一個值了,即葉子結點 if(start == end){ tree[node_index] = arr[start]; return; } int left_index = 2*node_index+1; int right_index = 2*node_index+2; int mid = start+(end-start)/2; //遞迴; build_tree(arr,tree,start,mid,left_index); build_tree(arr,tree,mid+1,end,right_index); //後序位置 tree[node_index] = tree[left_index]+tree[right_index]; } vector<int> ues_build(){int n = arr.size(); tree.resize(2*n,0); build_tree(arr,tree,0,n-1,0); return tree; } //查詢區間和 int query(vector<int> & arr,vector<int> & tree,int start,int end,int left,int right,int node_index){ if(left > end || right < start) return 0; else if(left<=start && end <= right) return tree[node_index]; else{ int mid = start+(end-start)/2; int left_node = 2*node_index+1; int right_node = 2*node_index+2; int left_sum = query(arr,tree,start,mid,left,right,left_node); int right_sum = query(arr,tree,mid+1,end,left,right,right_node); int sum = left_sum+right_sum; return sum; } } int ues_query(int left,int right){ return query(arr,tree,0,arr.size()-1,left,right,0); } //更新單點更新,arr陣列 //upadte_index為需要修改的arr中的數值下標,把值改成val void update(vector<int> & arr,vector<int> & tree,int start,int end,int node_index,int update_index,int val){ if(start == end) { arr[start] = val; tree[node_index] = arr[start]; } else{ int left_node = 2*node_index+1; int right_node = 2*(node_index+1); int mid = start+(end-start)/2; if(update_index <= mid){ update(arr,tree,start,mid,left_node,update_index,val); }else{ update(arr,tree,mid+1,end,right_node,update_index,val); } tree[node_index] = tree[left_node]+tree[right_node]; } } void use_update(int index,int val){ update(arr,tree,0,arr.size()-1,0,index,val); } }; int main() { vector<int> arr={93,90,50,50,1}; XianDuanTree * xian = new XianDuanTree(arr); vector<int> tree = xian->ues_build(); xian->use_update(4,2); for (int a:tree) { cout << a << " " <<endl; } int sum = xian->ues_query(2,4); return 0; }