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)
.我们需要进行区间修改以及区间查询,这里使用 线段树 来解决。
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); */