关于线段树的建树其实是一个递归的过程,建树,是由左儿子到右儿子依次开始建树
建树代码:
void BuildTree(int i , int left , int right)
{
node[i].left = left;//叶子节点的左区间
node[i].right = right;//叶子节点的右区间
node[i].value = 0;//根据提议不同,为不同的值,初始化为0
if(left == right)//如果左区间等于有区间,则将节点左界限保存在父数组。
{
father[left] = i;
//cout<<"father["<<left<<"] = "<<i<<endl;
return ;
}
BuildTree(i<<1,left,(int)floor((right +left)/2.0));//父节点的左儿子
BuildTree((i<<1)+1,(int)floor((right+left)/2.0)+1,right);//父节点的右儿子
}
单点更新代码:
void UpDate(int ri)
{
if(ri == 1) return ;//如果节点为1,则是线段树的根,所以,停止更新。
int fi = ri/2;
int a = node[(fi<<1)].value;//该节点的左儿子的值
int b = node[(fi<<1)+1].value;//该节点右儿子的值
node[fi].value = max(a,b);//改节点的值,为左儿子和右儿子的值的最大值
UpDate(ri/2);//递归继续向上更新
}
区间查询:
int Maxnn;
void Query(int i , int l , int r)
{
if(node[i].left == l && node[i].right == r)
{
//cout<< l<<" "<<r<<endl;
Maxnn = max(Maxnn,node[i].value);
return;
}
i = i << 1;
if(l <= node[i].right)
{
if(r <= node[i].right)
Query(i,l,r);
else
Query(i,l,node[i].right);
}
i ++;
if(r >= node[i].left)
{
if(l >= node[i].left)
Query(i,l,r);
else
Query(i,node[i].left,r);
}
}
hdu1752线段树代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxnode = 1 << 19;
const int Maxn = 2e6 + 10;
struct NODE
{
int left ,right;
int value;
}node[maxnode];
int father[Maxn];
void BuildTree(int i , int left , int right)
{
node[i].left = left;
node[i].right = right;
node[i].value = 0;
if(left == right)
{
father[left] = i;
//cout<<"father["<<left<<"] = "<<i<<endl;
return ;
}
BuildTree(i<<1,left,(int)floor((right +left)/2.0));
BuildTree((i<<1)+1,(int)floor((right+left)/2.0)+1,right);
}
void UpDate(int ri)
{
if(ri == 1) return ;
int fi = ri/2;
int a = node[(fi<<1)].value;
int b = node[(fi<<1)+1].value;
node[fi].value = max(a,b);
UpDate(ri/2);
}
int Maxnn;
void Query(int i , int l , int r)
{
if(node[i].left == l && node[i].right == r)
{
//cout<< l<<" "<<r<<endl;
Maxnn = max(Maxnn,node[i].value);
return;
}
i = i << 1;
if(l <= node[i].right)
{
if(r <= node[i].right)
Query(i,l,r);
else
Query(i,l,node[i].right);
}
i ++;
if(r >= node[i].left)
{
if(l >= node[i].left)
Query(i,l,r);
else
Query(i,node[i].left,r);
}
}
int main(void)
{
int n , m , q;
while(scanf("%d %d",&n , &m)!=EOF)
{
BuildTree(1,1,n);
for(int i = 1; i <= n ; i ++)
{
scanf("%d",&q);
node[father[i]].value = q;
UpDate(father[i]);
}
string p;
int a , b;
while(m --)
{
cin>>p>>a>>b;
if(p[0] == 'Q')
{
Maxnn = 0;
Query(1,a,b);
cout<<Maxnn<<endl;
}
else
{
node[father[a]].value = b;
UpDate(father[a]);
}
}
}
}