• 关于线段树的初步理解


    POJ 3264

    根据题目意思就是给定一段序列,然后给出几个区间,要求出该段区间中最大值与最小值之差。

    首先我想到的是用数组存储这一段序列,然后每次根据区间的左右边界来遍历这个段序列然后找到最大值和最小值,显然这样的方法是最容易想到的,但是可想而知这样的方法会耗费很多的时间,时间复杂度太大。

    然后,我进行了第二种思考,就是利用二维数组来存储左边界到右边界的最大值;

    (1)如果l==r,那么显然当前区间的最大值和最小值就是l这个位置的数本身

    (2)max1[i][j]=max{max[i][j-1],height[j]};

    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main(){
        int n,q;
        while(cin>>n>>q){
            int *height=new int[n];
            for(int i=0;i<n;i++){
                cin>>height[i];
            }
            int seta,setb;
            int max1[n][n];
            int min1[n][n];
            for(int i=0;i<n;i++){
                max1[i][i]=height[i];
                min1[i][i]=height[i];
            }
            for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    max1[i][j]=max(max1[i][j-1],height[j]);
                    min1[i][j]=min(min1[i][j-1],height[j]);
                }
            }
            while(q--){
                cin>>seta>>setb;
                cout<<max1[seta-1][setb-1]-min1[seta-1][setb-1]<<endl;
            }
        }
    }

    但是完成了这样的初步思考之后,由于原问题中的数据范围给的是50000,显然会超过给定的内存范围。

    于是,就发现了有线段树这个结构:

    #include <iostream>
    #include <algorithm>
    #define maxn 50000
    using namespace std;
    int MAX[maxn<<2];
    int MIN[maxn<<2];
    int A[maxn];
    void maximum(int rt){
        MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
    }
    void minmum(int rt){
        MIN[rt]=min(MIN[rt<<1],MIN[rt<<1|1]);
    }
    void Build(int l,int r,int rt){
        if(l==r){
            MAX[rt]=A[l];
            MIN[rt]=A[l];
            return ;
        }
        
        int m=(l+r)>>1;
        Build(l,m,rt<<1);
        Build(m+1,r,rt<<1|1);
        maximum(rt);
        minmum(rt);
    }
    int Query(int L,int R,int l,int r,int rt,int &x,int &y){
        if(L<=l&&R>=r){
            x=max(MAX[rt],x);
            y=min(MIN[rt],y);
            return x-y;
        }
        int m=(l+r)>>1;
        if(L<=m) {
            return Query(L,R,l,m,rt<<1,x,y);
        }
        else if(R>m){
            return Query(L,R,m+1,r,rt<<1|1,x,y);
        }
        
    }
    int main(){
        int n,m,L,R,x,y;
        while(cin>>n>>m){
            for(int i=0;i<n;i++){
                cin>>A[i];
            }
            Build(1,n,1);
            while(m--){
                x=-1,y=300000;
                cin>>L>>R;
            cout<<Query(L,R,1,n,1,x,y)<<endl;
            }
        }
        
        return 0;
    }

     就对于上述代码而言是根据查找某段区间的和来修改的,但是还需要对查找部分函数进行更深一步的了解。

  • 相关阅读:
    MySQL与Oracle 差异比较之七其它
    MySQL与Oracle 差异比较之七用户权限
    MySQL与Oracle 差异比较之六触发器
    MySQL与Oracle 差异比较之五存储过程&Function
    MySQL与Oracle 差异比较之四条件循环语句
    MySQL与Oracle 差异比较之三函数
    MySQL与Oracle 差异比较之二基本语法
    MySQL与Oracle 差异比较之一数据类型
    Nginx、fastCGI、php-fpm关系梳理
    RTSP服务器之————rtsp-server(轻量级RTSP / RTP流媒体服务器)
  • 原文地址:https://www.cnblogs.com/Sun-Yiwen-blog/p/9863858.html
Copyright © 2020-2023  润新知