线段树解决区间覆盖问题

问题:

给定一系列的区间,求其覆盖的区间的总长度。

/*************************************************************************
  * File Name: Solution.cpp
  * Description: 
  * Author: Yuji CAO
  * Mail: caoyuji@sogou-inc.com
  * Created_Time: 2015-08-03 10时44分46秒
  * Last modified: 2015-08-03 10时44分46秒
 ************************************************************************/
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<limits>
using namespace std;

struct TTNode{
    int _val;
    int _start;
    int _end;
    TTNode* _left;
    TTNode* _right;
    TTNode(int s,int e,int v):_val(v),_start(s),_end(e),_left(NULL),_right(NULL){}
    TTNode(const TTNode& ttn){
        this->_val=ttn._val;
        this->_start=ttn._start;
        this->_end=ttn._end;
        this->_left=ttn._left;
        this->_right=ttn._right;
    }
    TTNode& operator=(const TTNode& ttn){
        this->_val=ttn._val;
        this->_start=ttn._start;
        this->_end=ttn._end;
        this->_left=ttn._left;
        this->_right=ttn._right;
        return *this;
    }
    static void visit(TTNode* root){
        if(root==NULL){return;}
        cout<<"["<<root->_start<<","<<root->_end<<";"<<root->_val<<"]"<<endl;
        visit(root->_left);
        visit(root->_right);
    }
};

class TreadTree{
public:
    void build(TTNode* &cur,int l,int r){
        if(r==l+1){
            cur=new TTNode(l,r,0);
            return;
        }else{
            cur=new TTNode(l,r,0);
            build(cur->_left,l,(l+r)/2);
            build(cur->_right,(l+r)/2,r);
        }
    }
    void insert(TTNode* &root,int l,int r){
        if(l==r){
            return ;
        }
        if(root->_val==0){
            if(root->_start>=l&&root->_end<=r){
                root->_val=1;
                return ;
            }else{
                int mid=(root->_start+root->_end)/2;
                if(l<mid){
                    int e=min(mid,r);
                    insert(root->_left,l,e);
                }
                if(r>=mid){
                    int s=max(mid,l);
                    insert(root->_right,s,r);
                }
            }
        }
    }
    int query(TTNode* root){
        if(root==NULL){
            return 0;
        }
        if(root->_val==1){
            int ret=root->_end-root->_start;
            return ret;
        }else{
            int ret=0;
            ret+=query(root->_left);
            ret+=query(root->_right);
            return ret;
        }
    }
    void query(vector<TTNode>& result,TTNode* root,int start,int end){
        if(root->_start>start||root->_end<end){
            return;
        }
        if(root->_start==start&&root->_end==end){
            result.push_back(*root);
            return ;
        }
        int mid=(root->_start+root->_end)/2;
        if(start<=mid){
            int e=min(mid,end);
            query(result,root->_left,start,e);
        }
        if(end>mid){
            int e=min(end,root->_end);
            query(result,root->_right,mid,e);
        }
    }
};
struct Segment{
    int _start;
    int _end;
    Segment(int s,int e):_start(s),_end(e){}
};
/*
 *get result
 */
int getResult(vector<Segment>& dat){
    int b=numeric_limits<int>::max();
    int e=numeric_limits<int>::min();
    for(auto ele:dat){
        if(ele._start<b){
            b=ele._start;
        }
        if(ele._end>e){
            e=ele._end;
        }
    }

    TreadTree tt;
    TTNode* root=NULL;
    tt.build(root,b,e);
    for(auto ele:dat){
        tt.insert(root,ele._start,ele._end);
    }
    return tt.query(root);
}

int main(){
        int m;
        cin>>m;
        vector<Segment> dat;
        for(int i=0;i<m;++i){
            Segment sm(0,0);
            cin>>sm._start>>sm._end;
            dat.push_back(sm);
        }
        cout<<getResult(dat)<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值