leetcode715 Range模块


思路:

动态开点线段树,这里维护了区间赋值和区间和。

实现:

 1 class SegmentTree {
 2 public:
 3     int N = (int)1e9;
 4     class Node {
 5     public:
 6         // ls 和 rs 分别代表当前区间的左右子节点
 7         Node*ls=nullptr, *rs=nullptr;
 8         // val 代表当前区间的最大高度,add 为懒标记
 9         int val=0, add=-1;//add需要是赋值操作中未出现的值
10         Node(){}
11     };
12     vectornodes_pool;
13     Node*root = nullptr;
14     int cur_id=0;
15     SegmentTree(int n,int num_nodes){
16         N=n;
17         nodes_pool.resize(num_nodes);
18         root=&nodes_pool[cur_id++];
19     }
20     void update(int l,int r,int v){
21         _update(root,0,N,l,r,v);
22     }
23     void _update(Node*node, int lc, int rc, int l, int r, int v) {
24         if (l <= lc && rc <= r) {
25             node->add = v;
26             node->val = v*(rc-lc+1);
27             return ;
28         }
29         pushdown(node,lc,rc);
30         int mid = lc + rc >> 1;
31         if (l <= mid) _update(node->ls, lc, mid, l, r, v);
32         if (r > mid) _update(node->rs, mid + 1, rc, l, r, v);
33         pushup(node);
34     }
35     int query(int l,int r){
36         return _query(root,0,N,l,r);
37     }
38     int _query(Node*node, int lc, int rc, int l, int r) {
39         if (l <= lc && rc <= r) return node->val;
40         pushdown(node,lc,rc);
41         int mid = lc + rc >> 1, ans = 0;
42         if (l <= mid) ans = _query(node->ls, lc, mid, l, r);
43         if (r > mid) ans += _query(node->rs, mid + 1, rc, l, r);
44         return ans;
45     }
46     void pushdown(Node*node,int lc,int rc) {
47         if (node->ls == nullptr) node->ls = &nodes_pool[cur_id++];
48         if (node->rs == nullptr) node->rs = &nodes_pool[cur_id++];
49         if (node->add == -1) return ;//node->add初始值应为赋值操作中未出现的值,否则这里会混淆
50         int mid=lc+rc>>1;
51         node->ls->add = node->add; node->rs->add = node->add;
52         node->ls->val = node->add*(mid-lc+1); node->rs->val = node->add*(rc-mid);
53         node->add = -1;
54     }
55     void pushup(Node*node) {
56         node->val = node->ls->val + node->rs->val;
57     }
58 
59 };
60 class RangeModule {
61 public:
62     SegmentTree*st=NULL;
63     RangeModule() {
64         st=new SegmentTree(1e9,500000);
65     }
66     
67     void addRange(int left, int right) {
68         st->update(left,right-1,1);
69     }
70     
71     bool queryRange(int left, int right) {
72         int sum=st->query(left,right-1);
73         return sum==right-left;
74     }
75     
76     void removeRange(int left, int right) {
77         st->update(left,right-1,0);
78     }
79 };
80 
81 /**
82  * Your RangeModule object will be instantiated and called as such:
83  * RangeModule* obj = new RangeModule();
84  * obj->addRange(left,right);
85  */

相关