数据结构之线段树

线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。

对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。

因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度。

用线段树解题关键是要清楚的知道每个节点要存放什么信息,以及这些节点如何高效的更新,维护,查询,不一定每次都更新到叶子节点,这样复杂度最坏有可能是0(n)

下面附上一道题

poj3264

思路:用一维数组存放节点,节点数<=4n-1,每个节点存放该区间的最大值,最小值

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
int minV=INF;
int maxV=-INF;
//节点信息

struct Note
{
    int L,R;
    int minV,maxV;
    int Mid()
    {
        return (L+R)/2;
    }
};Note tree[800010];

//建树
void buildtree(int root,int L,int R)
{
    tree[root].L=L;
    tree[root].R=R;
    tree[root].minV=INF;
    tree[root].maxV=-INF;
    if(L!=R)
    {
        buildtree(root*2+1,L,(L+R)/2);
        buildtree(root*2+2,(L+R)/2+1,R);
    }
}

//插入
void insert(int root,int i,int v)
{
    if(tree[root].L==tree[root].R)
    {
        tree[root].minV=tree[root].maxV=v;
        return ;
    }
    tree[root].minV=min(v,tree[root].minV);
    tree[root].maxV=max(v,tree[root].maxV);
    if(i<=tree[root].Mid())
    {
        insert(2*root+1,i,v);
    }
    else
    {
        insert(2*root+2,i,v);
    }
}

//查询
void chaxun(int root,int s,int e)
{
    if(tree[root].minV>=minV&&tree[root].maxV<=maxV)
    {
        return ;
    }
    if(tree[root].L==s&&tree[root].R==e)
    {
        minV=min(minV,tree[root].minV);
        maxV=max(maxV,tree[root].maxV);
        return ;
    }
    if(e<=tree[root].Mid())
    {
        chaxun(2*root+1,s,e);
    }
    else if(s>tree[root].Mid())
    {
        chaxun(2*root+2,s,e);
    }
    else
    {
        chaxun(2*root+1,s,tree[root].Mid());
        chaxun(2*root+2,tree[root].Mid()+1,e);
    }
}
int main()
{
    int p,n;
    int i,h;
    while(scanf("%d%d",&n,&p)!=-1)
    {
        buildtree(0,1,n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&h);
            insert(0,i,h);
        }
        for(i=0;i<p;i++)
        {
            int s,e;
            scanf("%d%d",&s,&e);
            minV=INF;
            maxV=-INF;
            chaxun(0,s,e);
            printf("%d ",maxV-minV);
        }
    }
    return 0;

原文地址:https://www.cnblogs.com/ACWQYYY/p/4390501.html