• 线段树


    用一维数组存储二叉树,利用二分查找降低效率

    1.线段树的构造,区间查询

    描述:
    给定n(1<=n<=50000)个数,求任意区间中最大值最小值的差,
    
    eg:
    输入:
    6 3
    1 7 3 4 2 5 
    1 5
    4 6
    2 2
    输出:
    6 
    3
    0
    
    //balanced lineup  
    #include<iostream>
    #include<cstring>
    #include<climits>
    using namespace std;
    const int  maxn=50001;
    const int inf=INT_MAX;
    #define max(a,b) a>b?a:b
    #define min(a,b)  a<b?a:b
    #define L(a) ((a)<<1)         //左孩子 
    #define R(a) (((a)<<1)+1)     //右孩子
    
    typedef struct node_t{
        int left,right;
        int max,min; //区间里的最大值最小值 
    }node_t; 
    int A[maxn];//用作输入数据 0位置未用 
    /*完全二叉树 结点从1开始 层次从1开始
    用一维数组存储二叉树,空间约为4*n  */
    node_t node[4*maxn];  //数组存放结构体 
    int minx,maxx; //存放结果 
    void init(){
        memset(node,0,sizeof(node));
    }
    /*以t为结点,为区间A【l,r】建立线段树*/
    void build(int t,int l,int r){ //懂了 
        node[t].left=l;
        node[t].right=r;
        if(l==r) {
            node[t].max=node[t].min=A[l];
            return ;
        }
        const int mid=(l+r)/2;
        build(L(t),l,mid);
        build(R(t),mid+1,r);
        node[t].max=max(node[L(t)].max,node[R(t)].max);
        node[t].min=min(node[L(t)].min,node[R(t)].min);
    } 
    //查询根结点为t,区间A[l,r] 的最大值最小值 
    void query(int t,int l,int r){
        if(node[t].left==l&&node[t].right==r){
        if(maxx<node[t].max)  maxx=node[t].max;
        if(minx>node[t].min) minx=node[t].min;
        return ;}
        const int mid=(node[t].left+node[t].right)/2;
        if(l>mid){
            query(R(t),l,r);
        }else if(r<=mid){
            query(L(t),l,r);//
        }else {
            query(L(t),l,mid);
            query(R(t),mid+1,r);
        }
    }
    int main(){
        int n,q,i;
            int a,b;
        cin>>n;
        for(int i=1;i<=n;i++) cin>>A[i];
        init();
    //    cout<<"hello"<<endl; 
        build(1,1,n);
    //    cout<<"hello"<<endl;
        while(cin>>a>>b){
    //        cin>>a>>b;
            maxx=0;
            minx=inf;
    //        cout<<"hello"<<endl;
            query(1,a,b);    //A[a,b]之间的最大最小值 
    //        cout<<"helo"<<endl;
            cout<<maxx<<" "<<minx<<endl;
        } 
        return 0;
    } 
    View Code

    2.单点更新,区间求和     未完待续

  • 相关阅读:
    C语言寒假大作战01
    C语言I作业12—学期总结
    C语言I博客作业11
    C语言I博客作业10
    C语言I博客作业09
    C语言I博客作业08
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10496263.html
Copyright © 2020-2023  润新知