#include <iostream>
using namespace std;
const int N=100005;
typedef struct _Node
{
int left;
int right;
int max;
int sum;
}Node;
//这种线段树主要记录两种信息 当前最大值与其子树和
int a[N]={0,1,5,4,1,6};
Node nodeArray[N*4];
void PushIndex(int index,int begin,int end)
{
nodeArray[index].left=begin;
nodeArray[index].right=end;
nodeArray[index].max=std::max(nodeArray[index*2].max,nodeArray[index*2+1].max);
nodeArray[index].sum=nodeArray[index*2].max+nodeArray[index*2+1].max;
}
void Build(int index,int begin,int end)
{
if(begin==end)
{
nodeArray[index].left=begin;
nodeArray[index].right=end;
nodeArray[index].max=a[begin];
nodeArray[index].sum=a[begin];
return;
}
int mid=(begin+end)/2;
Build(index*2,begin,mid);
Build(index*2+1,mid+1,end);
PushIndex(index,begin,end);
}
void PrintNodeInformation(int index)
{
cout<<"下标是:"<<index<<endl;
cout<<"左右区间是"<<nodeArray[index].left<<"->"<<nodeArray[index].right<<endl;
cout<<"最大值是"<<nodeArray[index].max<<endl;
cout<<"和是"<<nodeArray[index].sum<<endl;
}
//线段树遍历
void Traverse(int index)
{
if(nodeArray[index].left==nodeArray[index].right)
{
PrintNodeInformation(index);
return ;
}
PrintNodeInformation(index);
Traverse(index*2);
Traverse(index*2+1);
return;
}
//更新线段树信息 从叶子节点开始更新 更新完后 向上回溯
void UpdateValue(int index,int pos,int value)
{
if(nodeArray[index].left==nodeArray[index].right&&nodeArray[index].left==pos)
{
nodeArray[index].max=nodeArray[index].sum=value;
return;
}
int mid=(nodeArray[index].left+nodeArray[index].right)/2;
if(pos<=mid)
{
UpdateValue(index*2,pos,value);
}
else
{
UpdateValue(index*2+1,pos,value);
}
nodeArray[index].sum=nodeArray[index*2].sum+nodeArray[index*2+1].sum;
nodeArray[index].max=std::max(nodeArray[index*2].max,nodeArray[index*2+1].max);
return;
}
//查询信息 此处为查询其和
int QuerySum(int index,int begin,int end)
{
if(nodeArray[index].left==begin&&nodeArray[index].right==end)
{
return nodeArray[index].sum;
}
int mid=(nodeArray[index].left+nodeArray[index].right)/2;
if(mid>=end)
return QuerySum(index*2,begin,end);
if(mid<begin)
return QuerySum(index*2+1,begin,end);
return QuerySum(index*2,begin,mid)+QuerySum(index*2+1,mid+1,end);
}
int main()
{
Build(1,1,5);//后两个参数,代表a数组的index,从1到5,也就是从a[1]到a[5]
// UpdateValue(1,2,100);//将a数组下标为2的元素改为100,并且从底向上更新其节点
cout<<"2到5之和为"<<QuerySum(1,2,5)<<endl;
// Traverse(1);
return 0;
}