线段树
来源:互联网 发布:mac口红chili专柜价格 编辑:程序博客网 时间:2024/04/29 04:14
//线段树,节点更新,区间求和#include <iostream>using namespace std;const int MAXN = 50000 + 100; //最大区间struct treeNode{ intleft; //左区间 intright; //右区间 intnum; //区间和}node[MAXN*3]; //节点数大约是最大区间的2倍,但是数组的下标要开到3倍int num[MAXN];int buildTree(int low, int top, int index)//功能:建树.父节点是左右子节点之和{ node[index].left= low; node[index].right= top; if(low == top) //是否已经递归到最低层 { node[index].num = num[low]; return node[index].num; } intmid = (low + top) / 2; //父节点为左右子节点之和 node[index].num= buildTree(low,mid,index*2) + buildTree(mid+1,top,index*2+1); returnnode[index].num;} void update(int k, int num, int index) //题目的更新是指节点上加上num{ node[index].num= node[index].num + num; //每一个覆盖的区间都加上num if(node[index].left == node[index].right && node[index].left == k) //已经更新到最底层并且找到K点 { return; } intmid = (node[index].left + node[index].right) / 2; if(k <= mid) //如果k在左子树中 { update(k,num,index*2); } else //如果k在右子树中 { update(k,num,index*2+1); }} int search(int low, int top, int index){ if(node[index].left == low && node[index].right == top) //找到完全重合的区间,直接返回该值,即为本次搜索的最终结果 { return node[index].num; } intmid = (node[index].left + node[index].right) / 2; if(top <= mid) //搜索区间位于左子树 { return search(low,top,index*2); } elseif(low > mid) //搜索区间位于右子树 { return search(low,top,index*2+1); } else //搜索区间在左右子树间,即将区间分成2部分 { return search(low,mid,index*2) +search(mid+1,top,index*2+1); }} int main(){ intn; cin>>n; //区间[1,n] for(int i=1; i<=n; i++) { cin>>num[i]; //每个点的初始值 } buildTree(1,n,1); //建树updata(3,10,1); //3号点增加10cout<<search(2,4,1); //区间[2,4]的总和 return0;}