hdu1752 线段树入门(区间查询,单点更新)

关于线段树的建树其实是一个递归的过程,建树,是由左儿子到右儿子依次开始建树

建树代码:

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]);
            }
            
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Zenith_Habitant/article/details/83654043