xinyu04

导航

[Google] LeetCode 715 Range Module 线段树

A Range Module is a module that tracks ranges of numbers. Design a data structure to track the ranges represented as half-open intervals and query about them.

A half-open interval [left, right) denotes all the real numbers x where left <= x < right.

Implement the RangeModule class:

  • RangeModule() Initializes the object of the data structure.
  • void addRange(int left, int right) Adds the half-open interval [left, right), tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval [left, right) that are not already tracked.
  • boolean queryRange(int left, int right) Returns true if every real number in the interval [left, right) is currently being tracked, and false otherwise.
  • void removeRange(int left, int right) Stops tracking every real number currently being tracked in the half-open interval [left, right).

Solution

我们需要进行区间修改以及区间查询,这里使用 线段树 来解决。

点击查看代码
class RangeModule {
private:
    struct node{
        bool val = false; 
        bool lazy = false;
        node* lt = NULL;
        node* rt = NULL;
    };
    int LIMIT = 1e9+1;
    node* root;
    queue<node*> nodeq;
    
    node* getNode(){
        if(nodeq.empty())return new node();
        else{
            node* nd = nodeq.front();
            nodeq.pop();
            if(nd->lt)nodeq.push(nd->lt);
            if(nd->rt)nodeq.push(nd->rt);
            
            nd->val = false; nd->lazy = false;
            nd->lt = NULL; nd->rt=NULL;
            return nd;
        }
    }
    
    bool query(node* nd, int s, int t, int l,int r){
        if(!nd->lt) nd->lt = getNode();
        if(!nd->rt) nd->rt = getNode();
        
        if(nd->lazy){
            nd->val|=nd->lazy;
            if(s!=t){
                nd->lt->lazy|=nd->lazy;
                nd->rt->lazy|=nd->lazy;
            }
            nd->lazy=false;
        }
        if(t<l || s>r) return true;
        if(nd->val) return nd->val;
        if(l<=s && t<=r) return nd->val;
        int mid = s + (t-s)/2;
        return query(nd->lt, s, mid,l,r) && query(nd->rt, mid+1, t, l,r);
        
    }
    
    void upd(node* nd, int s, int t, int l, int r){
        if(!nd->lt) nd->lt = getNode();
        if(!nd->rt) nd->rt = getNode();
        if(nd->lazy) {
            nd->val|=nd->lazy;
            if(s!=t){
                nd->lt->lazy |= nd->lazy;
                nd->rt->lazy |= nd->lazy;
            }
            nd->lazy = false;
        }
        if(t<l || s>r) return;
        if(nd->val) return;
        
        if(l<=s && t<=r){
            nd->val=true;
            if(s!=t){
                nd->lt->lazy=true;
                nd->rt->lazy=true;
            }
            return;
        }
        int mid=s+(t-s)/2;
        upd(nd->lt, s, mid, l,r);
        upd(nd->rt, mid+1, t, l, r);
        
        nd->val = nd->lt->val && nd->rt->val;
    }
    
    void rmv(node* nd, int s,int t, int l,int r){
        if(t<l || s>r) return;
        if(l<=s && t<= r){
            nd->val = false; nd->lazy = false;
            if(nd->lt) nodeq.push(nd->lt);
            if(nd->rt) nodeq.push(nd->rt);
            nd->lt = NULL; nd->rt = NULL;
            return;
        }
        if(!nd->lt) nd->lt = getNode();
        if(!nd->rt) nd->rt = getNode();
        
        if(nd->lazy){
            nd->val|=nd->lazy;
            if(s!=t){
                nd->lt->lazy|=nd->lazy;
                nd->rt->lazy|=nd->lazy;
            }
            nd->lazy = false;
        }
        int mid = s+(t-s)/2;
        rmv(nd->lt, s, mid, l,r);
        rmv(nd->rt, mid+1, t, l, r);
        nd->val = nd->lt->val && nd->rt->val;
    }
    
public:
    RangeModule() {
        root = new node();
    }
    
    void addRange(int left, int right) {
        upd(root, 0, LIMIT, left, right-1);
    }
    
    bool queryRange(int left, int right) {
        return query(root, 0, LIMIT, left, right-1);
    }
    
    void removeRange(int left, int right) {
        rmv(root, 0, LIMIT, left, right-1);
    }
};

/**
 * Your RangeModule object will be instantiated and called as such:
 * RangeModule* obj = new RangeModule();
 * obj->addRange(left,right);
 * bool param_2 = obj->queryRange(left,right);
 * obj->removeRange(left,right);
 */

posted on 2022-08-30 20:17  Blackzxy  阅读(24)  评论(0编辑  收藏  举报