[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)
Returnstrue
if every real number in the interval[left, right)
is currently being tracked, andfalse
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);
*/