线段树

//线段树,节点更新,区间求和
#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号点增加10
cout<<search(2,4,1);  //区间[2,4]的总和
       return0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值