From 287f55040eb1e3b3fb57819203bef1dd6a1f6c97 Mon Sep 17 00:00:00 2001 From: Suri-Feng <56166228+Suri-Feng@users.noreply.github.com> Date: Sun, 5 Jun 2022 19:04:48 -0700 Subject: [PATCH 01/35] Update 210.Course-Schedule-II.cpp when index is small, array might be faster than unordered_map --- BFS/210.Course-Schedule-II/210.Course-Schedule-II.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BFS/210.Course-Schedule-II/210.Course-Schedule-II.cpp b/BFS/210.Course-Schedule-II/210.Course-Schedule-II.cpp index 70e244298..6c49299f9 100644 --- a/BFS/210.Course-Schedule-II/210.Course-Schedule-II.cpp +++ b/BFS/210.Course-Schedule-II/210.Course-Schedule-II.cpp @@ -3,8 +3,8 @@ class Solution { vector findOrder(int numCourses, vector>& prerequisites) { int n = numCourses; - unordered_map>nextCourses(n); - unordered_mapdegree(n); + vector>nextCourses(n); + vectordegree(n, 0); for (auto edge: prerequisites) { From 3de10b8399eae914f0c5e464802b2731d406bbbb Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:38:22 -0700 Subject: [PATCH 02/35] Create range_max.cpp --- Template/SegmentTree/range_max.cpp | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Template/SegmentTree/range_max.cpp diff --git a/Template/SegmentTree/range_max.cpp b/Template/SegmentTree/range_max.cpp new file mode 100644 index 000000000..6b084e3a6 --- /dev/null +++ b/Template/SegmentTree/range_max.cpp @@ -0,0 +1,99 @@ +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + int info; // the max height of the range + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] + { + tag = 0; + start = a, end = b; + if (a==b) + { + info = val; + return; + } + int mid = (a+b)/2; + if (left==NULL) + { + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = max(left->info, right->info); // write your own logic + } + } + + void pushDown() + { + if (tag==1 && left) + { + left->info = info; + right->info = info; + left->tag = 1; + right->tag = 1; + tag = 0; + } + } + + void updateRange(int a, int b, int val) + { + if (b < start || a > end ) // no intersection + return; + + if (a <= start && end <=b) + { + info = val; + tag = 1; + return; + } + + if (left) + { + pushDown(); + left->updateRange(a, b, val); + right->updateRange(a, b, val); + info = max(left->info, right->info); // write your own logic + } + } + + int queryRange(int a, int b) + { + if (b < start || a > end ) + { + return 0; // write your own logic + } + if (a <= start && end <=b) + { + return info; // write your own logic + } + + if (left) + { + pushDown(); + int ret = max(left->queryRange(a, b), right->queryRange(a, b)); + info = max(left->info, right->info); + return ret; + } + + return info; + } + +}; + +int main() +{ + SegTreeNode* root = new SegTreeNode(0, length-1); + + for (auto& update: updates) + { + int start = update[0], end = update[1], val = update[2]; + root->updateRange(start, end ,val); // set the range [start, end] with val + } + + vectorrets(length); + for (int i=0; iqueryRange(i, i); // get single node val + return rets; +} From c922f7badec9b1e66fdb5710f728d90e011fd81a Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:42:18 -0700 Subject: [PATCH 03/35] Update range_max.cpp --- Template/SegmentTree/range_max.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Template/SegmentTree/range_max.cpp b/Template/SegmentTree/range_max.cpp index 6b084e3a6..919ad89af 100644 --- a/Template/SegmentTree/range_max.cpp +++ b/Template/SegmentTree/range_max.cpp @@ -4,10 +4,10 @@ class SegTreeNode SegTreeNode* left = NULL; SegTreeNode* right = NULL; int start, end; - int info; // the max height of the range + int info; // the maximum value of the range bool tag; - SegTreeNode(int a, int b, int val) // init for range [a,b] + SegTreeNode(int a, int b, int val) // init for range [a,b] with val { tag = 0; start = a, end = b; @@ -21,7 +21,7 @@ class SegTreeNode { left = new SegTreeNode(a, mid, val); right = new SegTreeNode(mid+1, b, val); - info = max(left->info, right->info); // write your own logic + info = max(left->info, right->info); // check with your own logic } } @@ -37,12 +37,11 @@ class SegTreeNode } } - void updateRange(int a, int b, int val) + void updateRange(int a, int b, int val) // set range [a,b] with val { - if (b < start || a > end ) // no intersection - return; - - if (a <= start && end <=b) + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] { info = val; tag = 1; @@ -58,26 +57,26 @@ class SegTreeNode } } - int queryRange(int a, int b) + int queryRange(int a, int b) // query the maximum value within range [a,b] { if (b < start || a > end ) { - return 0; // write your own logic + return 0; // check with your own logic } if (a <= start && end <=b) { - return info; // write your own logic + return info; // check with your own logic } if (left) { pushDown(); int ret = max(left->queryRange(a, b), right->queryRange(a, b)); - info = max(left->info, right->info); + info = max(left->info, right->info); // check with your own logic return ret; } - return info; + return info; // should not reach here } }; From 0c2f74d20089bb932c9893679244b3d3e594d625 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:46:14 -0700 Subject: [PATCH 04/35] Update 699.Falling-Squares_SegmentTree_LazyTag.cpp --- ...99.Falling-Squares_SegmentTree_LazyTag.cpp | 132 +++++++++--------- 1 file changed, 69 insertions(+), 63 deletions(-) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegmentTree_LazyTag.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegmentTree_LazyTag.cpp index 0e33f2a38..5a4297587 100644 --- a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegmentTree_LazyTag.cpp +++ b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegmentTree_LazyTag.cpp @@ -1,80 +1,87 @@ -class Solution { - class SegTreeNode - { - public: - SegTreeNode* left; - SegTreeNode* right; - int start, end; - int info; // the max height of the range - bool tag; - SegTreeNode(int a, int b):start(a),end(b),info(0),tag(0),left(NULL),right(NULL){} - }; - - void init(SegTreeNode* node, int a, int b) // init for range [a,b] - { +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + int info; // the maximum value of the range + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] with val + { + tag = 0; + start = a, end = b; if (a==b) { - node->info = 0; + info = val; return; - } + } int mid = (a+b)/2; - if (node->left==NULL) + if (left==NULL) { - node->left = new SegTreeNode(a, mid); - node->right = new SegTreeNode(mid+1, b); - } - init(node->left, a, mid); - init(node->right, mid+1, b); - - node->info = 0; // write your own logic - } + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = max(left->info, right->info); // check with your own logic + } + } - void updateRange(SegTreeNode* node, int a, int b, int val) + void pushDown() + { + if (tag==1 && left) + { + left->info = info; + right->info = info; + left->tag = 1; + right->tag = 1; + tag = 0; + } + } + + void updateRange(int a, int b, int val) // set range [a,b] with val { - if (b < node->start || a > node->end ) // no intersection - return; - if (a <= node->start && node->end <=b) + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] { - node->info = val; - node->tag = 1; + info = val; + tag = 1; return; } - - pushDown(node); - updateRange(node->left, a, b, val); - updateRange(node->right, a, b, val); - - node->info = max(node->left->info, node->right->info); // write your own logic + + if (left) + { + pushDown(); + left->updateRange(a, b, val); + right->updateRange(a, b, val); + info = max(left->info, right->info); // write your own logic + } } - int queryRange(SegTreeNode* node, int a, int b) + int queryRange(int a, int b) // query the maximum value within range [a,b] { - if (b < node->start || a > node->end ) + if (b < start || a > end ) { - return 0; // write your own logic + return 0; // check with your own logic } - if (a <= node->start && b>=node->end) + if (a <= start && end <=b) { - return node->info; // write your own logic - } - pushDown(node); - node->info = max(queryRange(node->left, a, b), queryRange(node->right, a, b)); // write your own logic - return node->info; - } - - void pushDown(SegTreeNode* node) - { - if (node->tag==true) + return info; // check with your own logic + } + + if (left) { - node->left->info = node->info; - node->right->info = node->info; - node->left->tag = 1; - node->right->tag = 1; - node->tag = 0; - } + pushDown(); + int ret = max(left->queryRange(a, b), right->queryRange(a, b)); + info = max(left->info, right->info); // check with your own logic + return ret; + } + + return info; // should not reach here } - - + +}; + +class Solution { public: vector fallingSquares(vector>& positions) { @@ -93,8 +100,7 @@ class Solution { } int n = pos2idx.size(); - SegTreeNode* root = new SegTreeNode(0, n-1); - init(root, 0, n-1); + SegTreeNode* root = new SegTreeNode(0, n-1, 0); int maxH = 0; vectorrets; @@ -102,8 +108,8 @@ class Solution { { int a = pos2idx[rect[0]]; int b = pos2idx[rect[0]+rect[1]]; - int h = queryRange(root, a, b-1); // [a,b) - updateRange(root, a, b-1, h + rect[1]); + int h = root->queryRange(a, b-1); // [a,b) + root->updateRange(a, b-1, h + rect[1]); maxH = max(maxH, h + rect[1]); rets.push_back(maxH); } From a57433c72e7e31f81c77568bc199beadbd642b41 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:47:04 -0700 Subject: [PATCH 05/35] Rename 699.Falling-Squares_SegmentTree_LazyTag.cpp to 699.Falling-Squares_SegTree_v2.cpp --- ...SegmentTree_LazyTag.cpp => 699.Falling-Squares_SegTree_v2.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/699.Falling-Squares/{699.Falling-Squares_SegmentTree_LazyTag.cpp => 699.Falling-Squares_SegTree_v2.cpp} (100%) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegmentTree_LazyTag.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp similarity index 100% rename from Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegmentTree_LazyTag.cpp rename to Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp From 91fd1973552349b79b53e3acc19441bce217af31 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:47:32 -0700 Subject: [PATCH 06/35] Update and rename 699.Falling-Squares_segTree.cpp to 699.Falling-Squares_SegTree_v1.cpp --- ...g-Squares_segTree.cpp => 699.Falling-Squares_SegTree_v1.cpp} | 2 ++ 1 file changed, 2 insertions(+) rename Segment_Tree/699.Falling-Squares/{699.Falling-Squares_segTree.cpp => 699.Falling-Squares_SegTree_v1.cpp} (98%) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_segTree.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp similarity index 98% rename from Segment_Tree/699.Falling-Squares/699.Falling-Squares_segTree.cpp rename to Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp index ad65408b7..8a470ef40 100644 --- a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_segTree.cpp +++ b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp @@ -1,3 +1,5 @@ +// 支持动态开点 + class Solution { class SegTree { From 3cbb303d33fe3689b2a84bebef4ee300a03c9d30 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:59:34 -0700 Subject: [PATCH 07/35] Update 699.Falling-Squares_SegTree_v1.cpp --- .../699.Falling-Squares_SegTree_v1.cpp | 113 +++++++++--------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp index 8a470ef40..7aa698df2 100644 --- a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp +++ b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp @@ -1,73 +1,74 @@ -// 支持动态开点 +// 动态开点 -class Solution { - class SegTree +class SegTree +{ + public: + int start,end,status; + SegTree* left; + SegTree* right; + SegTree(int a,int b,int s):start(a),end(b),status(s),left(NULL),right(NULL){} + + void remove(SegTree* &node) + { + if (node==NULL) return; + remove(node->left); + remove(node->right); + delete node; + node=NULL; + return; + } + + void setStatus(int a, int b, int s) { - public: - int start,end,status; - SegTree* left; - SegTree* right; - SegTree(int a,int b,int s):start(a),end(b),status(s),left(NULL),right(NULL){} - - void remove(SegTree* &node) + if (a<=start && b>=end) { - if (node==NULL) return; - remove(node->left); - remove(node->right); - delete node; - node=NULL; + remove(left); + remove(right); + status = s; return; } - - void setStatus(int a, int b, int s) - { - if (a<=start && b>=end) - { - remove(left); - remove(right); - status = s; - return; - } - if (a>=end || b<=start) - return; - if (left==NULL) - { - int mid = (end-start)/2+start; - left = new SegTree(start,mid,status); - right = new SegTree(mid,end,status); - } - left->setStatus(a,b,s); - right->setStatus(a,b,s); - status = max(left->status,right->status); + if (a>=end || b<=start) return; - } - - int getStatus(int a, int b) + if (left==NULL) { - if (a<=start && b>=end) - return status; - if (a>=end || b<=start) - return 0; - if (left==NULL) - return status; - int L = left->getStatus(a,b); - int R = right->getStatus(a,b); - return max(L,R); - } - }; + int mid = (end-start)/2+start; + left = new SegTree(start,mid,status); + right = new SegTree(mid,end,status); + } + left->setStatus(a,b,s); + right->setStatus(a,b,s); + status = max(left->status,right->status); + return; + } + + int getStatus(int a, int b) + { + if (a<=start && b>=end) + return status; + if (a>=end || b<=start) + return 0; + if (left==NULL) + return status; + int L = left->getStatus(a,b); + int R = right->getStatus(a,b); + return max(L,R); + } +}; + +class Solution { public: - vector fallingSquares(vector>& positions) + vector fallingSquares(vector>& positions) { - SegTree root = SegTree(0,1e9,0); + SegTree* root = new SegTree(0,1e9,0); vectorresult; int curMax = 0; for (auto p:positions) { - int cur = root.getStatus(p.first,p.first+p.second); - curMax = max(curMax, cur+p.second); - root.setStatus(p.first,p.first+p.second, cur+p.second); + int cur = root->getStatus(p[0], p[0]+p[1]); + curMax = max(curMax, cur+p[1]); + root->setStatus(p[0], p[0]+p[1], cur+p[1]); result.push_back(curMax); } - return result; + return result; } }; From f25b0b168802d4f07c1f8a5770ac8de528df2acc Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 21:59:47 -0700 Subject: [PATCH 08/35] Update 699.Falling-Squares_SegTree_v1.cpp --- .../699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp index 7aa698df2..b7baf53a0 100644 --- a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp +++ b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v1.cpp @@ -1,4 +1,4 @@ -// 动态开点 +// 线段树可动态开点 class SegTree { From e277cf196eb57d36a8bcbeda5ae7fac7cbe12b26 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:00:16 -0700 Subject: [PATCH 09/35] Update 699.Falling-Squares_SegTree_v2.cpp --- .../699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp index 5a4297587..6f0cbb4ba 100644 --- a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp +++ b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp @@ -1,3 +1,5 @@ +// 线段树大小在初始化时固定。支持Lazy Tag(延迟标记) + class SegTreeNode { public: From c5eade98536c40849ce3827a785bf53c8bd267b6 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:00:37 -0700 Subject: [PATCH 10/35] Rename 699.Falling-Squares.cpp to 699.Falling-Squares_Heap_v1.cpp --- .../{699.Falling-Squares.cpp => 699.Falling-Squares_Heap_v1.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/699.Falling-Squares/{699.Falling-Squares.cpp => 699.Falling-Squares_Heap_v1.cpp} (100%) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_Heap_v1.cpp similarity index 100% rename from Segment_Tree/699.Falling-Squares/699.Falling-Squares.cpp rename to Segment_Tree/699.Falling-Squares/699.Falling-Squares_Heap_v1.cpp From b14ca1ad5cee0ba44da07e2ce4df00e0a0a47e83 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:00:49 -0700 Subject: [PATCH 11/35] Rename 699.Falling-Squares-v2.cpp to 699.Falling-Squares_Heap_v2.cpp --- ...699.Falling-Squares-v2.cpp => 699.Falling-Squares_Heap_v2.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/699.Falling-Squares/{699.Falling-Squares-v2.cpp => 699.Falling-Squares_Heap_v2.cpp} (100%) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares-v2.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_Heap_v2.cpp similarity index 100% rename from Segment_Tree/699.Falling-Squares/699.Falling-Squares-v2.cpp rename to Segment_Tree/699.Falling-Squares/699.Falling-Squares_Heap_v2.cpp From 384f39fd19a2b1eb9e277166beb7c8ec22188c35 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:05:19 -0700 Subject: [PATCH 12/35] Update and rename 218.The-Skyline-Problem_segTree.cpp to 218.The-Skyline-Problem_SegTree_v1.cpp --- .../218.The-Skyline-Problem_SegTree_v1.cpp | 81 +++++++++++++++++++ .../218.The-Skyline-Problem_segTree.cpp | 78 ------------------ 2 files changed, 81 insertions(+), 78 deletions(-) create mode 100644 Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v1.cpp delete mode 100644 Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_segTree.cpp diff --git a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v1.cpp b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v1.cpp new file mode 100644 index 000000000..63c87774c --- /dev/null +++ b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v1.cpp @@ -0,0 +1,81 @@ +// 支持动态开点 + +class SegTree +{ + public: + int start,end,status; + SegTree* left; + SegTree* right; + SegTree(int a, int b, int s):start(a),end(b),status(s),left(NULL),right(NULL){} + + void remove(SegTree* &node) + { + if (node==NULL) return; + remove(node->left); + remove(node->right); + delete node; + node = NULL; + return; + } + + void setStatus(int a, int b, int s) + { + if (a>=end || b<=start) + return; + if (a<=start && b>=end && s>=status) + { + remove(left); + remove(right); + status = s; + return; + } + if (a<=start && b>=end && ssetStatus(a,b,s); + right->setStatus(a,b,s); + status = max(left->status,right->status); + } +}; + +class Solution { +public: + vector>results; + vector> getSkyline(vector>& buildings) + { + if (buildings.size()==0) return {}; + + SegTree* root = new SegTree(0,INT_MAX,0); + for (auto q:buildings) + root->setStatus(q[0],q[1],q[2]); + + DFS(root); + if (results.back()[1]!=0) results.push_back({INT_MAX,0}); + + vector>filteredResults; + for (auto p: results) + { + if (filteredResults.size()!=0 && p[1]==filteredResults.back()[1]) + continue; + filteredResults.push_back({p[0],p[1]}); + } + if (filteredResults.size()!=0 && filteredResults[0][1]==0) filteredResults.erase(filteredResults.begin()); + return filteredResults; + } + + void DFS(SegTree* node) + { + if (node->left==NULL) + results.push_back({node->start,node->status}); + else + { + DFS(node->left); + DFS(node->right); + } + } +}; diff --git a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_segTree.cpp b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_segTree.cpp deleted file mode 100644 index ced18e620..000000000 --- a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_segTree.cpp +++ /dev/null @@ -1,78 +0,0 @@ -class Solution { - class SegTree - { - public: - int start,end,status; - SegTree* left; - SegTree* right; - SegTree(int a, int b, int s):start(a),end(b),status(s),left(NULL),right(NULL){} - - void remove(SegTree* &node) - { - if (node==NULL) return; - remove(node->left); - remove(node->right); - delete node; - node = NULL; - return; - } - - void setStatus(int a, int b, int s) - { - if (a>=end || b<=start) - return; - if (a<=start && b>=end && s>=status) - { - remove(left); - remove(right); - status = s; - return; - } - if (a<=start && b>=end && ssetStatus(a,b,s); - right->setStatus(a,b,s); - status = max(left->status,right->status); - } - }; -public: - vector>results; - vector> getSkyline(vector>& buildings) - { - if (buildings.size()==0) return {}; - - SegTree* root = new SegTree(0,INT_MAX,0); - for (auto q:buildings) - root->setStatus(q[0],q[1],q[2]); - - DFS(root); - if (results.back().second!=0) results.push_back({INT_MAX,0}); - - vector>filteredResults; - for (auto p: results) - { - if (filteredResults.size()!=0 && p.second==filteredResults.back().second) - continue; - filteredResults.push_back({p.first,p.second}); - } - if (filteredResults.size()!=0 && filteredResults[0].second==0) filteredResults.erase(filteredResults.begin()); - return filteredResults; - } - - void DFS(SegTree* node) - { - if (node->left==NULL) - results.push_back({node->start,node->status}); - else - { - DFS(node->left); - DFS(node->right); - } - } -}; From 2d2b21586129df63ddc87862cc6905b556589492 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:08:22 -0700 Subject: [PATCH 13/35] Update and rename 218.The-Skyline-Problem_SegmentTree_lazyTag.cpp to 218.The-Skyline-Problem_SegTree_v2.cpp --- .../218.The-Skyline-Problem_SegTree_v2.cpp | 141 ++++++++++++++++++ ...he-Skyline-Problem_SegmentTree_lazyTag.cpp | 124 --------------- 2 files changed, 141 insertions(+), 124 deletions(-) create mode 100644 Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v2.cpp delete mode 100644 Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegmentTree_lazyTag.cpp diff --git a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v2.cpp b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v2.cpp new file mode 100644 index 000000000..2327a837c --- /dev/null +++ b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegTree_v2.cpp @@ -0,0 +1,141 @@ +// 线段树大小在初始化时固定。支持Lazy Tag(延迟标记) + +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + int info; // the maximum value of the range + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] with val + { + tag = 0; + start = a, end = b; + if (a==b) + { + info = val; + return; + } + int mid = (a+b)/2; + if (left==NULL) + { + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = max(left->info, right->info); // check with your own logic + } + } + + void pushDown() + { + if (tag==1 && left) + { + left->info = info; + right->info = info; + left->tag = 1; + right->tag = 1; + tag = 0; + } + } + + void updateRange(int a, int b, int val) // set range [a,b] with val + { + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] + { + info = val; + tag = 1; + return; + } + + if (left) + { + pushDown(); + left->updateRange(a, b, val); + right->updateRange(a, b, val); + info = max(left->info, right->info); // write your own logic + } + } + + int queryRange(int a, int b) // query the maximum value within range [a,b] + { + if (b < start || a > end ) + { + return INT_MIN; // check with your own logic + } + if (a <= start && end <=b) + { + return info; // check with your own logic + } + + if (left) + { + pushDown(); + int ret = max(left->queryRange(a, b), right->queryRange(a, b)); + info = max(left->info, right->info); // check with your own logic + return ret; + } + + return info; // should not reach here + } + +}; + +class Solution { + vector>height; // {idx, h} +public: + vector> getSkyline(vector>& buildings) + { + setSet; + for (auto & building: buildings) + { + Set.insert(building[0]); + Set.insert(building[1]); + } + int id = 0; + unordered_mappos2idx; + unordered_mapidx2pos; + for (auto x:Set) + { + pos2idx[x] = id; + idx2pos[id] = x; + id++; + } + + int n = pos2idx.size(); + SegTreeNode* root = new SegTreeNode(0, n-1, 0); + + sort(buildings.begin(), buildings.end(), [](vector&a, vector&b){return a[2]updateRange(pos2idx[building[0]], pos2idx[building[1]]-1, building[2]); + } + + DFS(root); + + vector>rets; + for (int i=0; istart==node->end || node->tag==1) + { + height.push_back({node->start, node->info}); + return; + } + DFS(node->left); + DFS(node->right); + } + +}; diff --git a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegmentTree_lazyTag.cpp b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegmentTree_lazyTag.cpp deleted file mode 100644 index 861a04078..000000000 --- a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem_SegmentTree_lazyTag.cpp +++ /dev/null @@ -1,124 +0,0 @@ -class Solution { - class SegTreeNode - { - public: - SegTreeNode* left; - SegTreeNode* right; - int start, end; - int info; - int tag; - SegTreeNode(int a, int b):start(a),end(b),info(0),tag(0),left(NULL),right(NULL){} - }; - - void init(SegTreeNode* node, int a, int b) // init for range [a,b] - { - if (a==b) - { - node->info = 0; - return; - } - int mid = (a+b)/2; - if (node->left==NULL) - { - node->left = new SegTreeNode(a, mid); - node->right = new SegTreeNode(mid+1, b); - } - init(node->left, a, mid); - init(node->right, mid+1, b); - - node->info = 0; // write your own logic - } - - void updateRange(SegTreeNode* node, int a, int b, int val) - { - if (b < node->start || a > node->end ) - return; - if (node->start == node->end) - { - node->info = max(node->info, val); - return; - } - if (a <= node->start && node->end <=b && val >= node->info) - { - // write your own logic - node->info = val; - node->tag = 1; - return; - } - - pushDown(node); - node->info = max(node->info, val); - - updateRange(node->left, a, b, val); - updateRange(node->right, a, b, val); - } - - - void pushDown(SegTreeNode* node) - { - if (node->tag!=0) - { - node->left->info = node->info; - node->right->info = node->info; - node->left->tag = 1; - node->right->tag = 1; - node->tag = 0; - } - } - - vector>height; // {idx, h} -public: - vector> getSkyline(vector>& buildings) - { - setSet; - for (auto & building: buildings) - { - Set.insert(building[0]); - Set.insert(building[1]); - } - int id = 0; - unordered_mappos2idx; - unordered_mapidx2pos; - for (auto x:Set) - { - pos2idx[x] = id; - idx2pos[id] = x; - id++; - } - - int n = pos2idx.size(); - SegTreeNode* root = new SegTreeNode(0, n-1); - init(root, 0, n-1); - - sort(buildings.begin(), buildings.end(), [](vector&a, vector&b){return a[2]>rets; - for (int i=0; istart==node->end || node->tag==1) - { - height.push_back({node->start, node->info}); - return; - } - DFS(node->left); - DFS(node->right); - } - -}; From 7b78f707560f4b10618f477a8ffdca8cbc365434 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:08:59 -0700 Subject: [PATCH 14/35] Update range_max.cpp --- Template/SegmentTree/range_max.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Template/SegmentTree/range_max.cpp b/Template/SegmentTree/range_max.cpp index 919ad89af..2bf955870 100644 --- a/Template/SegmentTree/range_max.cpp +++ b/Template/SegmentTree/range_max.cpp @@ -61,7 +61,7 @@ class SegTreeNode { if (b < start || a > end ) { - return 0; // check with your own logic + return INT_MIN; // check with your own logic } if (a <= start && end <=b) { From e349c5eebc6c7d353edf7a305f833155853e9f76 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:10:10 -0700 Subject: [PATCH 15/35] Update 699.Falling-Squares_SegTree_v2.cpp --- .../699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp index 6f0cbb4ba..9b43d96b8 100644 --- a/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp +++ b/Segment_Tree/699.Falling-Squares/699.Falling-Squares_SegTree_v2.cpp @@ -63,7 +63,7 @@ class SegTreeNode { if (b < start || a > end ) { - return 0; // check with your own logic + return INT_MIN; // check with your own logic } if (a <= start && end <=b) { From d8bf11bd6433bb11d6d7d3c3bfb0d30893b22dca Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:19:45 -0700 Subject: [PATCH 16/35] Create range_sum.cpp --- Template/SegmentTree/range_sum.cpp | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Template/SegmentTree/range_sum.cpp diff --git a/Template/SegmentTree/range_sum.cpp b/Template/SegmentTree/range_sum.cpp new file mode 100644 index 000000000..4eebd6dd5 --- /dev/null +++ b/Template/SegmentTree/range_sum.cpp @@ -0,0 +1,99 @@ +using LL = long long; +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + LL info; // the sum value over the range + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] with val + { + tag = 0; + start = a, end = b; + if (a==b) + { + info = val; + return; + } + int mid = (a+b)/2; + if (left==NULL) + { + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = left->info + right->info; // check with your own logic + } + } + + void pushDown() + { + if (tag==1 && left) + { + left->info = info; + right->info = info; + left->tag = 1; + right->tag = 1; + tag = 0; + } + } + + void updateRange(int a, int b, int val) // set range [a,b] with val + { + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] + { + info = val * (end-start+1); + tag = 1; + return; + } + + if (left) + { + pushDown(); + left->updateRange(a, b, val); + right->updateRange(a, b, val); + info = left->info + right->info; // write your own logic + } + } + + LL queryRange(int a, int b) // query the maximum value within range [a,b] + { + if (b < start || a > end ) + { + return 0; // check with your own logic + } + if (a <= start && end <=b) + { + return info; // check with your own logic + } + + if (left) + { + pushDown(); + LL ret = left->queryRange(a, b) + right->queryRange(a, b); + info = left->info + right->info; // check with your own logic + return ret; + } + + return info; // should not reach here + } +}; + +int main() +{ + SegTreeNode* root = new SegTreeNode(0, length-1); + + for (auto& update: updates) + { + int start = update[0], end = update[1], val = update[2]; + root->updateRange(start, end ,val); // set the range [start, end] with val + } + + for (auto& query: queries) + { + int start = query[0], end = query[1]; + ret[i] = root->updateRange(start, end); // get the range sum over [start, end] + } +} From ec66da36d4b9eb03f7b4453dc865fda5f34fec09 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:20:24 -0700 Subject: [PATCH 17/35] Delete SegmentTree_Basic.cpp --- Template/SegmentTree/SegmentTree_Basic.cpp | 80 ---------------------- 1 file changed, 80 deletions(-) delete mode 100644 Template/SegmentTree/SegmentTree_Basic.cpp diff --git a/Template/SegmentTree/SegmentTree_Basic.cpp b/Template/SegmentTree/SegmentTree_Basic.cpp deleted file mode 100644 index b04fcffe8..000000000 --- a/Template/SegmentTree/SegmentTree_Basic.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// LeetCode 307. Range Sum Query - Mutable - -class NumArray { - class SegTreeNode - { - public: - SegTreeNode* left; - SegTreeNode* right; - int start, end; - int info; - SegTreeNode(int a, int b):start(a),end(b),info(0),left(NULL),right(NULL){} - }; - - void init(SegTreeNode* node, int a, int b) // init for range [a,b] - { - if (a==b) - { - node->info = nums[a]; - return; - } - int mid = (a+b)/2; - if (node->left==NULL) - { - node->left = new SegTreeNode(a, mid); - node->right = new SegTreeNode(mid+1, b); - } - init(node->left, a, mid); - init(node->right, mid+1, b); - - node->info = node->left->info + node->right->info; // write your own logic - } - - void updateSingle(SegTreeNode* node, int id, int val) - { - if (id < node->start || id > node->end ) return; - if (node->start == node->end) - { - node->info = val; - return; - } - updateSingle(node->left, id, val); - updateSingle(node->right, id, val); - node->info = node->left->info + node->right->info; // write your own logic - } - - int queryRange(SegTreeNode* node, int a, int b) - { - if (b < node->start || a > node->end ) - { - return 0; // write your own logic - } - if (a <= node->start && b>=node->end) - { - return node->info; // write your own logic - } - return queryRange(node->left, a, b) + queryRange(node->right, a, b); // write your own logic - } - - vector nums; - SegTreeNode* root; - -public: - NumArray(vector nums) - { - this->nums = nums; - root = new SegTreeNode(0, nums.size()-1); - init(root, 0, nums.size()-1); - } - - void update(int i, int val) - { - updateSingle(root, i, val); - } - - int sumRange(int i, int j) - { - return queryRange(root, i, j); - } -}; - From e806c19a0ae668204ed3e5cfa99781466d5bb2a4 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:20:30 -0700 Subject: [PATCH 18/35] Delete SegmentTree_LazyTag.cpp --- Template/SegmentTree/SegmentTree_LazyTag.cpp | 101 ------------------- 1 file changed, 101 deletions(-) delete mode 100644 Template/SegmentTree/SegmentTree_LazyTag.cpp diff --git a/Template/SegmentTree/SegmentTree_LazyTag.cpp b/Template/SegmentTree/SegmentTree_LazyTag.cpp deleted file mode 100644 index add214c04..000000000 --- a/Template/SegmentTree/SegmentTree_LazyTag.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// LeetCode 370. Range Addition - -class Solution { - class SegTreeNode - { - public: - SegTreeNode* left; - SegTreeNode* right; - int start, end; - int info; - int tag; - SegTreeNode(int a, int b):start(a),end(b),info(0),tag(0),left(NULL),right(NULL){} - }; - - void init(SegTreeNode* node, int a, int b) // init for range [a,b] - { - if (a==b) - { - node->info = 0; - return; - } - int mid = (a+b)/2; - if (node->left==NULL) - { - node->left = new SegTreeNode(a, mid); - node->right = new SegTreeNode(mid+1, b); - } - init(node->left, a, mid); - init(node->right, mid+1, b); - - node->info = node->left->info + node->right->info; // write your own logic - } - - void updateRangeBy(SegTreeNode* node, int a, int b, int val) - { - if (b < node->start || a > node->end ) return; - if (a <= node->start && node->end <=b) - { - // write your own logic - node->info += val * len(node); - node->tag += val; - return; - } - - pushDown(node); - updateRangeBy(node->left, a, b, val); - updateRangeBy(node->right, a, b, val); - - node->info = node->left->info + node->right->info; // write your own logic - } - - int len(SegTreeNode* node) - { - return node->end - node->start + 1; - } - - void pushDown(SegTreeNode* node) - { - if (node->tag!=0) - { - node->left->info += len(node->left) * node->tag; - node->right->info += len(node->right) * node->tag; - node->left->tag += node->tag; - node->right->tag += node->tag; - node->tag = 0; - } - } - - int queryRange(SegTreeNode* node, int a, int b) - { - if (b < node->start || a > node->end ) - { - return 0; // write your own logic - } - if (a <= node->start && b>=node->end) - { - return node->info; // write your own logic - } - pushDown(node); - return queryRange(node->left, a, b) + queryRange(node->right, a, b); // write your own logic - } - - SegTreeNode* root; - -public: - vector getModifiedArray(int length, vector>& updates) - { - SegTreeNode* root = new SegTreeNode(0, length-1); - - init(root, 0, length-1); - - for (auto& update: updates) - { - updateRangeBy(root, update[0], update[1], update[2]); - } - vectorrets(length); - for (int i=0; i Date: Sun, 5 Jun 2022 22:33:28 -0700 Subject: [PATCH 19/35] Update 370.Range-Addition_SegmentTree_lazyTag.cpp --- ...370.Range-Addition_SegmentTree_lazyTag.cpp | 136 +++++++++--------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/Segment_Tree/370.Range-Addition/370.Range-Addition_SegmentTree_lazyTag.cpp b/Segment_Tree/370.Range-Addition/370.Range-Addition_SegmentTree_lazyTag.cpp index d26b0c13d..14e9e8d19 100644 --- a/Segment_Tree/370.Range-Addition/370.Range-Addition_SegmentTree_lazyTag.cpp +++ b/Segment_Tree/370.Range-Addition/370.Range-Addition_SegmentTree_lazyTag.cpp @@ -1,98 +1,104 @@ -class Solution { - class SegTreeNode - { - public: - SegTreeNode* left; - SegTreeNode* right; - int start, end; - int info; - int tag; - SegTreeNode(int a, int b):start(a),end(b),info(0),tag(0),left(NULL),right(NULL){} - }; - - void init(SegTreeNode* node, int a, int b) // init for range [a,b] - { +using LL = long long; +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + LL info; // the sum value over the range + LL delta; + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] with val + { + tag = 0; + delta = 0; + start = a, end = b; if (a==b) { - node->info = 0; + info = val; return; - } + } int mid = (a+b)/2; - if (node->left==NULL) + if (left==NULL) { - node->left = new SegTreeNode(a, mid); - node->right = new SegTreeNode(mid+1, b); - } - init(node->left, a, mid); - init(node->right, mid+1, b); - - node->info = 0; // write your own logic - } + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = left->info + right->info; // check with your own logic + } + } - void updateRange(SegTreeNode* node, int a, int b, int val) + void pushDown() { - if (b < node->start || a > node->end ) - return; - if (a <= node->start && b>=node->end) + if (tag==1 && left) { - node->info += val * (node->end-node->start+1); - node->tag += val; - return; - } - - pushdown(node); // erase lazy tag and propagate down - updateRange(node->left, a, b, val); - updateRange(node->right, a, b, val); - } + left->delta += delta; + right->delta += delta; + left->tag = 1; + right->tag = 1; + tag = 0; + delta = 0; + } + } - void pushdown(SegTreeNode* node) - { - if (node->tag != 0) + void updateRangeBy(int a, int b, int val) // set range [a,b] with val + { + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] { - node->left->tag += node->tag; - node->right->tag += node->tag; - node->left->info += node->tag * (node->left->end-node->left->start+1); - node->right->info += node->tag * (node->right->end-node->right->start+1); - node->tag = 0; + delta += val; + tag = 1; + return; } + + if (left) + { + pushDown(); + left->updateRangeBy(a, b, val); + right->updateRangeBy(a, b, val); + info = left->info + right->info; // write your own logic + } } - int querySingle(SegTreeNode* node, int id) + LL queryRange(int a, int b) // query the maximum value within range [a,b] { - if (id < node->start || id > node->end ) + if (b < start || a > end ) { - return INT_MAX; // write your own logic + return 0; // check with your own logic } - if (node->start==id && node->end==id) + if (a <= start && end <=b) { - return node->info; + return info + delta*(end-start+1); // check with your own logic + } + + if (left) + { + pushDown(); + LL ret = left->queryRange(a, b) + right->queryRange(a, b); + info = left->info + right->info; // check with your own logic + return ret; } - pushdown(node); - int a = querySingle(node->left, id); - int b = querySingle(node->right, id); - if (a!=INT_MAX) return a; - else if (b!=INT_MAX) return b; - else return INT_MAX; - } - - - + return info; // should not reach here + } +}; + +class Solution { public: vector getModifiedArray(int length, vector>& updates) { - SegTreeNode* root = new SegTreeNode(0, length-1); - init(root, 0, length-1); + SegTreeNode* root = new SegTreeNode(0, length-1, 0); for (auto update: updates) { - updateRange(root, update[0], update[1], update[2]); + root->updateRangeBy(update[0], update[1], update[2]); } vectorrets(length); for (int i=0; iqueryRange(i, i); } return rets; From 4a3ea52b7bffe3eed039b16f8c0786f701951982 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:33:44 -0700 Subject: [PATCH 20/35] Rename 370.Range-Addition_SegmentTree_lazyTag.cpp to 370.Range-Addition_SegTree_v2.cpp --- ..._SegmentTree_lazyTag.cpp => 370.Range-Addition_SegTree_v2.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/370.Range-Addition/{370.Range-Addition_SegmentTree_lazyTag.cpp => 370.Range-Addition_SegTree_v2.cpp} (100%) diff --git a/Segment_Tree/370.Range-Addition/370.Range-Addition_SegmentTree_lazyTag.cpp b/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree_v2.cpp similarity index 100% rename from Segment_Tree/370.Range-Addition/370.Range-Addition_SegmentTree_lazyTag.cpp rename to Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree_v2.cpp From 45a4754906a02d48007c0a452f53d513afecc7b7 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:34:38 -0700 Subject: [PATCH 21/35] Update Readme.md --- Segment_Tree/370.Range-Addition/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Segment_Tree/370.Range-Addition/Readme.md b/Segment_Tree/370.Range-Addition/Readme.md index c8dbe7097..2ad786890 100644 --- a/Segment_Tree/370.Range-Addition/Readme.md +++ b/Segment_Tree/370.Range-Addition/Readme.md @@ -1,9 +1,9 @@ ### 370.Range-Addition -#### 解法1: +#### 解法1:差分数组 此题比较简单的解法是用差分数组```diff```。```diff[i]```表示```nums[i]```比```nums[i-1]```大多少。这样如果已知```nums[i-1]```,那么就有```diff[i]=nums[i-1]+diff[i]```。本题中的三元参数```update(i,j,k)```恰好就是给出了这样的差分数组的信息:```diff[i]+=k, diff[j+1]-=k```. -#### 解法2: +#### 解法2:线段树 本题和307很相似,也可以用线段树来实现。最大的区别就是本题中需要实现的是区间更新。在线段树的basic版本中(LC307),我们实现的都是单点更新,用单点更新来实现区间更细,效率肯定很低。 本题实现的是线段树的进阶版本,使用lazy tag来实现区间更新的延迟推广。具体的说,我们想要将区间[a:b]增加1时,不一定需要立即下沉到每个叶子节点将其info增1。如果我们没有对[a:b]中的任何一个叶子节点做查询的话,意味着不需要任何下沉操作。我们只增加[a:b]对应的节点的info,但同时标记该节点的tag为1。如果以后某个时刻,我们需要下沉访问某个下层区间或者叶子节点,那么在下沉的过程中必然会重新经过[a:b]对应的node,此时我们顺便将tag信息读入并在访问下层区间或叶子节点时,将它们的info加上这个“延迟加载”的1就行。 From aa41220d60c9de700ac5198e37f1b4f48e8c1b3d Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:35:03 -0700 Subject: [PATCH 22/35] Rename 370.Range-Addition.cpp to 370.Range-Addition_DiffArray.cpp --- .../{370.Range-Addition.cpp => 370.Range-Addition_DiffArray.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/370.Range-Addition/{370.Range-Addition.cpp => 370.Range-Addition_DiffArray.cpp} (100%) diff --git a/Segment_Tree/370.Range-Addition/370.Range-Addition.cpp b/Segment_Tree/370.Range-Addition/370.Range-Addition_DiffArray.cpp similarity index 100% rename from Segment_Tree/370.Range-Addition/370.Range-Addition.cpp rename to Segment_Tree/370.Range-Addition/370.Range-Addition_DiffArray.cpp From 99675442af6c3ef01499345559d92a14d5a48ec9 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:35:12 -0700 Subject: [PATCH 23/35] Delete 370.Range-Addition_segTree.cpp --- .../370.Range-Addition_segTree.cpp | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 Segment_Tree/370.Range-Addition/370.Range-Addition_segTree.cpp diff --git a/Segment_Tree/370.Range-Addition/370.Range-Addition_segTree.cpp b/Segment_Tree/370.Range-Addition/370.Range-Addition_segTree.cpp deleted file mode 100644 index 8849e611c..000000000 --- a/Segment_Tree/370.Range-Addition/370.Range-Addition_segTree.cpp +++ /dev/null @@ -1,50 +0,0 @@ -class Solution { - class SegTree - { - public: - int start,end,status; - SegTree* left; - SegTree* right; - SegTree(int a, int b, int s):start(a),end(b),status(s),left(NULL),right(NULL){} - - void setStatus(int a, int b, int s) - { - if (a<=start && b>=end && left==NULL) // bottom node condition 1; - { - status += s; - return; - } - if (a>=end || b<=start) // bottom node condition 2; - return; - int mid = start+(end-start)/2; - if (left==NULL) // no children? create them - { - left = new SegTree(start,mid,status); - right = new SegTree(mid,end,status); - } // recursion - left->setStatus(a,b,s); - right->setStatus(a,b,s); - } - }; -public: - vector getModifiedArray(int length, vector>& updates) - { - SegTree* root = new SegTree(0,length,0); - for (auto x:updates) - root->setStatus(x[0],x[1]+1,x[2]); - vectorresults(length); - DFS(root,results); - return results; - } - void DFS(SegTree* node, vector&results) - { - if (node->left!=NULL) - { - DFS(node->left,results); - DFS(node->right,results); - return; - } - for (int i=node->start; iend; i++) - results[i] = node->status; - } -}; From 3fb99e68fc594b827594963e609a75c502432094 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:35:23 -0700 Subject: [PATCH 24/35] Rename 370.Range-Addition_SegTree_v2.cpp to 370.Range-Addition_SegTree.cpp --- ...nge-Addition_SegTree_v2.cpp => 370.Range-Addition_SegTree.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/370.Range-Addition/{370.Range-Addition_SegTree_v2.cpp => 370.Range-Addition_SegTree.cpp} (100%) diff --git a/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree_v2.cpp b/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp similarity index 100% rename from Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree_v2.cpp rename to Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp From c2fb4131365019447bae3e67089017d87455e8a3 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:35:45 -0700 Subject: [PATCH 25/35] Update 370.Range-Addition_SegTree.cpp --- Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp b/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp index 14e9e8d19..aedfcc976 100644 --- a/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp +++ b/Segment_Tree/370.Range-Addition/370.Range-Addition_SegTree.cpp @@ -41,7 +41,7 @@ class SegTreeNode } } - void updateRangeBy(int a, int b, int val) // set range [a,b] with val + void updateRangeBy(int a, int b, int val) // increase range [a,b] by val { if (b < start || a > end ) // not covered by [a,b] at all return; From 3caca8a52d630e1467284fa6586d53f32390a89a Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:36:16 -0700 Subject: [PATCH 26/35] Create range_sum_increase_by.cpp --- .../SegmentTree/range_sum_increase_by.cpp | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Template/SegmentTree/range_sum_increase_by.cpp diff --git a/Template/SegmentTree/range_sum_increase_by.cpp b/Template/SegmentTree/range_sum_increase_by.cpp new file mode 100644 index 000000000..578a1f61f --- /dev/null +++ b/Template/SegmentTree/range_sum_increase_by.cpp @@ -0,0 +1,85 @@ +using LL = long long; +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + LL info; // the sum value over the range + LL delta; + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] with val + { + tag = 0; + delta = 0; + start = a, end = b; + if (a==b) + { + info = val; + return; + } + int mid = (a+b)/2; + if (left==NULL) + { + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = left->info + right->info; // check with your own logic + } + } + + void pushDown() + { + if (tag==1 && left) + { + left->delta += delta; + right->delta += delta; + left->tag = 1; + right->tag = 1; + tag = 0; + delta = 0; + } + } + + void updateRangeBy(int a, int b, int val) // increase range [a,b] by val + { + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] + { + delta += val; + tag = 1; + return; + } + + if (left) + { + pushDown(); + left->updateRangeBy(a, b, val); + right->updateRangeBy(a, b, val); + info = left->info + right->info; // write your own logic + } + } + + LL queryRange(int a, int b) // query the maximum value within range [a,b] + { + if (b < start || a > end ) + { + return 0; // check with your own logic + } + if (a <= start && end <=b) + { + return info + delta*(end-start+1); // check with your own logic + } + + if (left) + { + pushDown(); + LL ret = left->queryRange(a, b) + right->queryRange(a, b); + info = left->info + right->info; // check with your own logic + return ret; + } + + return info; // should not reach here + } +}; From 0a04cc0a450d7d7bcdf8d55dc7f668b8f318b4ba Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:41:15 -0700 Subject: [PATCH 27/35] Update Readme.md --- Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 9944d615a..a02f8c91e 100644 --- a/Readme.md +++ b/Readme.md @@ -271,12 +271,10 @@ [1902](https://github.com/wisdompeak/LeetCode/tree/master/Tree/1902.Depth-of-BST-Given-Insertion-Order), #### [Segment Tree](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/) -* ``Basics`` [307.Range-Sum-Query-Mutable](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/307.Range-Sum-Query-Mutable/) (H-) [1526.Minimum-Number-of-Increments-on-Subarrays-to-Form-a-Target-Array](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/1526.Minimum-Number-of-Increments-on-Subarrays-to-Form-a-Target-Array) (H-) [1649.Create-Sorted-Array-through-Instructions](https://github.com/wisdompeak/LeetCode/tree/master/Divide_Conquer/1649.Create-Sorted-Array-through-Instructions) (H-) [1157.Online-Majority-Element-In-Subarray](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/1157.Online-Majority-Element-In-Subarray) (H) -* ``Lazy Tag`` [370.Range-Addition](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/370.Range-Addition) (H) [218.The-Skyline-Problem](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/218.The-Skyline-Problem) (H+) [699.Falling-Squares](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/699.Falling-Squares) (H) @@ -1229,6 +1227,7 @@ * ``扫描线 / 差分数组`` [252.Meeting-Rooms](https://github.com/wisdompeak/LeetCode/tree/master/Others/252.Meeting-Rooms) (M) [253.Meeting-Rooms-II](https://github.com/wisdompeak/LeetCode/tree/master/Others/253.Meeting-Rooms-II) (M+) +[370.Range-Addition](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/370.Range-Addition) (H-) [056.Merge-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Others/056.Merge-Intervals) (M) [057.Insert-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Others/057.Insert-Interval) (M) [732.My-Calendar-III](https://github.com/wisdompeak/LeetCode/tree/master/Others/732.My-Calendar-III) (M) From 3fe5b5450cbf301aaa706264c215c25a6dbce455 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:44:16 -0700 Subject: [PATCH 28/35] Create range_module.cpp --- Template/SegmentTree/range_module.cpp | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Template/SegmentTree/range_module.cpp diff --git a/Template/SegmentTree/range_module.cpp b/Template/SegmentTree/range_module.cpp new file mode 100644 index 000000000..98b214af6 --- /dev/null +++ b/Template/SegmentTree/range_module.cpp @@ -0,0 +1,90 @@ +// 支持动态增减节点 + +class SegTree +{ + public: + int start, end; + bool status; + SegTree* left; + SegTree* right; + SegTree(int a, int b, bool T):start(a),end(b),status(T),left(NULL),right(NULL){} + + void remove(SegTree* &node) + { + if (node==NULL) return; + remove(node->left); + remove(node->right); + delete node; + node = NULL; + return; + } + + void setStatus(int a, int b, bool T) + { + if (a<=start && b>=end) // bottom condition 1: [a,b)>[start,end) + { + remove(left); + remove(right); + status = T; + return; + } + if (a>=end || b<=start) // bottom condition 2: [a,b) do not intersect with [start,end) + return; + int mid = start+(end-start)/2; + if (left==NULL) // no children? create them! + { + left = new SegTree(start,mid,status); + right = new SegTree(mid,end,status); + } + left->setStatus(a,b,T); + right->setStatus(a,b,T); + status =left->status && right->status; + } + + bool getStatus(int a, int b) + { + if (a<=start && b>=end) // bottom condition 1: [a,b)>[start,end) + return status; + if (a>=end || b<=start) // bottom condition 2: [a,b) do not intersect with [start,end) + return true; + if (left==NULL) + return status; + int mid = start+(end-start)/2; + bool L = left->getStatus(a,b); + bool R = right->getStatus(a,b); + return L&&R; + } +}; + +class RangeModule { +public: + + SegTree root = SegTree(0,1e9,false); + + RangeModule() + { + } + + void addRange(int left, int right) + { + root.setStatus(left,right,true); + } + + bool queryRange(int left, int right) + { + return root.getStatus(left,right); + } + + void removeRange(int left, int right) + { + root.setStatus(left,right,false); + } +}; + +/** + * 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); + */ From 225b84577a5f9d9741b78afa892763f0002d0cfd Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:44:24 -0700 Subject: [PATCH 29/35] Delete SegmentTree_LazyTag_Discretization.cpp --- .../SegmentTree_LazyTag_Discretization.cpp | 113 ------------------ 1 file changed, 113 deletions(-) delete mode 100644 Template/SegmentTree/SegmentTree_LazyTag_Discretization.cpp diff --git a/Template/SegmentTree/SegmentTree_LazyTag_Discretization.cpp b/Template/SegmentTree/SegmentTree_LazyTag_Discretization.cpp deleted file mode 100644 index 6fc580be6..000000000 --- a/Template/SegmentTree/SegmentTree_LazyTag_Discretization.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// LeetCode 699. Falling Squares - -class Solution { - class SegTreeNode - { - public: - SegTreeNode* left; - SegTreeNode* right; - int start, end; - int info; // the max height of the range - bool tag; - SegTreeNode(int a, int b):start(a),end(b),info(0),tag(0),left(NULL),right(NULL){} - }; - - void init(SegTreeNode* node, int a, int b) // init for range [a,b] - { - if (a==b) - { - node->info = 0; - return; - } - int mid = (a+b)/2; - if (node->left==NULL) - { - node->left = new SegTreeNode(a, mid); - node->right = new SegTreeNode(mid+1, b); - } - init(node->left, a, mid); - init(node->right, mid+1, b); - - node->info = 0; // write your own logic - } - - void updateRange(SegTreeNode* node, int a, int b, int val) - { - if (b < node->start || a > node->end ) // no intersection - return; - if (a <= node->start && node->end <=b) - { - node->info = val; - node->tag = 1; - return; - } - - pushDown(node); - updateRange(node->left, a, b, val); - updateRange(node->right, a, b, val); - - node->info = max(node->left->info, node->right->info); // write your own logic - } - - int queryRange(SegTreeNode* node, int a, int b) - { - if (b < node->start || a > node->end ) - { - return 0; // write your own logic - } - if (a <= node->start && b>=node->end) - { - return node->info; // write your own logic - } - pushDown(node); - return max(queryRange(node->left, a, b), queryRange(node->right, a, b)); // write your own logic - } - - void pushDown(SegTreeNode* node) - { - if (node->tag==true) - { - node->left->info = node->info; - node->right->info = node->info; - node->left->tag = 1; - node->right->tag = 1; - node->tag = 0; - } - } - - -public: - vector fallingSquares(vector>& positions) - { - setSet; - for (auto & rect: positions) - { - Set.insert(rect[0]); - Set.insert(rect[0]+rect[1]); - } - unordered_mappos2idx; - int idx = 0; - for (auto x: Set) - { - pos2idx[x] = idx; - idx++; - } - int n = pos2idx.size(); - - SegTreeNode* root = new SegTreeNode(0, n-1); - init(root, 0, n-1); - - int maxH = 0; - vectorrets; - for (auto & rect: positions) - { - int a = pos2idx[rect[0]]; - int b = pos2idx[rect[0]+rect[1]]; - int h = queryRange(root, a, b-1); // [a,b) - updateRange(root, a, b-1, h + rect[1]); - maxH = max(maxH, h + rect[1]); - rets.push_back(maxH); - } - return rets; - } -}; From 67d0c05c6deb6a7c979a252ac364c2939e61ef5e Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:55:19 -0700 Subject: [PATCH 30/35] Create 2286.Booking-Concert-Tickets-in-Groups.cpp --- ...2286.Booking-Concert-Tickets-in-Groups.cpp | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp diff --git a/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp new file mode 100644 index 000000000..d3f2b7a33 --- /dev/null +++ b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp @@ -0,0 +1,239 @@ +using LL = long long; + +class SegTreeNode +{ + public: + SegTreeNode* left = NULL; + SegTreeNode* right = NULL; + int start, end; + int info; // the max height of the range + bool tag; + + SegTreeNode(int a, int b, int val) // init for range [a,b] + { + tag = 0; + start = a, end = b; + if (a==b) + { + info = val; + return; + } + int mid = (a+b)/2; + if (left==NULL) + { + left = new SegTreeNode(a, mid, val); + right = new SegTreeNode(mid+1, b, val); + info = max(left->info, right->info); // write your own logic + } + } + + void pushDown() + { + if (tag==1 && left) + { + left->info = info; + right->info = info; + left->tag = 1; + right->tag = 1; + tag = 0; + } + } + + void updateRange(int a, int b, int val) + { + if (b < start || a > end ) // no intersection + return; + + if (a <= start && end <=b) + { + info = val; + tag = 1; + return; + } + + if (left) + { + pushDown(); + left->updateRange(a, b, val); + right->updateRange(a, b, val); + info = max(left->info, right->info); // write your own logic + } + } + + int queryRange(int a, int b) + { + if (b < start || a > end ) + { + return INT_MIN; // write your own logic + } + if (a <= start && end <=b) + { + return info; // write your own logic + } + + if (left) + { + pushDown(); + int ret = max(left->queryRange(a, b), right->queryRange(a, b)); + info = max(left->info, right->info); + return ret; + } + + return info; + } + +}; + + +class SegTreeNode2 +{ + public: + SegTreeNode2* left = NULL; + SegTreeNode2* right = NULL; + int start, end; + LL info; // the sum value over the range + bool tag; + + SegTreeNode2(int a, int b, int val) // init for range [a,b] with val + { + tag = 0; + start = a, end = b; + if (a==b) + { + info = val; + return; + } + int mid = (a+b)/2; + if (left==NULL) + { + left = new SegTreeNode2(a, mid, val); + right = new SegTreeNode2(mid+1, b, val); + info = left->info + right->info; // check with your own logic + } + } + + void pushDown() + { + if (tag==1 && left) + { + left->info = info; + right->info = info; + left->tag = 1; + right->tag = 1; + tag = 0; + } + } + + void updateRange(int a, int b, int val) // set range [a,b] with val + { + if (b < start || a > end ) // not covered by [a,b] at all + return; + if (a <= start && end <=b) // completely covered within [a,b] + { + info = val * (end-start+1); + tag = 1; + return; + } + + if (left) + { + pushDown(); + left->updateRange(a, b, val); + right->updateRange(a, b, val); + info = left->info + right->info; // write your own logic + } + } + + LL queryRange(int a, int b) // query the maximum value within range [a,b] + { + if (b < start || a > end ) + { + return 0; // check with your own logic + } + if (a <= start && end <=b) + { + return info; // check with your own logic + } + + if (left) + { + pushDown(); + LL ret = left->queryRange(a, b) + right->queryRange(a, b); + info = left->info + right->info; // check with your own logic + return ret; + } + + return info; // should not reach here + } + +}; + +class BookMyShow { + int n,m; + vectorleft; + int p = 0; + SegTreeNode* root; + SegTreeNode2* root2; + + +public: + BookMyShow(int n, int m) { + this->n = n; + this->m = m; + left.resize(n); + for (int i=0; i gather(int k, int maxRow) + { + int l = 0, r = maxRow; + while (lqueryRange(0, mid) >= k ) + r = mid; + else + l = mid+1; + } + + if (root->queryRange(0, l) < k ) + return {}; + + left[l] -= k; + root->updateRange(l, l, left[l]); + root2->updateRange(l, l, left[l]); + + return {l,m-(left[l]+k)}; + } + + bool scatter(int k, int maxRow) + { + if (root2->queryRange(0, maxRow) < k) + return false; + + while (k>0) + { + int t = min(k, left[p]); + left[p] -= t; + root->updateRange(p, p, left[p]); + root2->updateRange(p, p, left[p]); + k -= t; + if (left[p]==0) p++; + } + + return true; + } +}; + +/** + * Your BookMyShow object will be instantiated and called as such: + * BookMyShow* obj = new BookMyShow(n, m); + * vector param_1 = obj->gather(k,maxRow); + * bool param_2 = obj->scatter(k,maxRow); + */ From c0c253ea668c4c3fd554252a80508d48cb5f8781 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:56:20 -0700 Subject: [PATCH 31/35] Rename Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp to Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp --- .../2286.Booking-Concert-Tickets-in-Groups.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Segment_Tree/{ => 2286.Booking-Concert-Tickets-in-Groups}/2286.Booking-Concert-Tickets-in-Groups.cpp (100%) diff --git a/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp similarity index 100% rename from Segment_Tree/2286.Booking-Concert-Tickets-in-Groups.cpp rename to Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp From 8a3543b9c15f8c588ec336b9a43009b718e42ded Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 22:56:54 -0700 Subject: [PATCH 32/35] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index a02f8c91e..8ff41002a 100644 --- a/Readme.md +++ b/Readme.md @@ -278,8 +278,8 @@ [370.Range-Addition](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/370.Range-Addition) (H) [218.The-Skyline-Problem](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/218.The-Skyline-Problem) (H+) [699.Falling-Squares](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/699.Falling-Squares) (H) -* ``Others`` [715.Range-Module](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/715.Range-Module) (H) +[2286.Booking-Concert-Tickets-in-Groups](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups) (H-) #### [Binary Index Tree] [307.Range-Sum-Query-Mutable](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/307.Range-Sum-Query-Mutable/) (M) From 2bd117e7ccd6d012aa4e87cd17d337db4f328a67 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 23:12:00 -0700 Subject: [PATCH 33/35] Update 2286.Booking-Concert-Tickets-in-Groups.cpp --- ...2286.Booking-Concert-Tickets-in-Groups.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp index d3f2b7a33..daec800cc 100644 --- a/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp +++ b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/2286.Booking-Concert-Tickets-in-Groups.cpp @@ -170,7 +170,7 @@ class SegTreeNode2 class BookMyShow { int n,m; - vectorleft; + vectorseats; int p = 0; SegTreeNode* root; SegTreeNode2* root2; @@ -180,10 +180,10 @@ class BookMyShow { BookMyShow(int n, int m) { this->n = n; this->m = m; - left.resize(n); + seats.resize(n); for (int i=0; iqueryRange(0, l) < k ) return {}; - left[l] -= k; - root->updateRange(l, l, left[l]); - root2->updateRange(l, l, left[l]); + seats[l] -= k; + root->updateRange(l, l, seats[l]); + root2->updateRange(l, l, seats[l]); - return {l,m-(left[l]+k)}; + return {l,m-(seats[l]+k)}; } bool scatter(int k, int maxRow) @@ -219,12 +219,12 @@ class BookMyShow { while (k>0) { - int t = min(k, left[p]); - left[p] -= t; - root->updateRange(p, p, left[p]); - root2->updateRange(p, p, left[p]); + int t = min(k, seats[p]); + seats[p] -= t; + root->updateRange(p, p, seats[p]); + root2->updateRange(p, p, seats[p]); k -= t; - if (left[p]==0) p++; + if (seats[p]==0) p++; } return true; From d931aab76e26fe33c106a6fcd4ad5b98aaedaeab Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 23:19:31 -0700 Subject: [PATCH 34/35] Create Readme.md --- .../2286.Booking-Concert-Tickets-in-Groups/Readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/Readme.md diff --git a/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/Readme.md b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/Readme.md new file mode 100644 index 000000000..5059c6ae3 --- /dev/null +++ b/Segment_Tree/2286.Booking-Concert-Tickets-in-Groups/Readme.md @@ -0,0 +1,9 @@ +### 2286.Booking-Concert-Tickets-in-Groups + +根据题意,我们需要给维护一个数组seats,代表每一行剩余的座椅数目。 + +如果遇到的是scatter,那么我们就从前往后查看每一行,有任何剩余的座位就都分配出去。如果某一行的座位都已经被scatter分配完了,那么这意味着该行及其之前的行都没有空座了,今后可以忽略。所以我们需要一个指针p,来指向当前仍有作为剩余的最小行号。但是这里有一个问题,如果对于某个scatter query,我们试图一行一行地去查询和分配座位后,发现无法满足要求(所有分配的座位必须在指定的maxRow之前)。于是我们需要有一个函数,支持查看[0,maxRow]这个区间内还剩多少个座位。如果查询得知剩余座位不够,就可以直接返回false。如果查询得知剩余座位足够,我们再逐行更新```seats[p]```,将分配完所有座位的行号都置零。显然,这是区间求和,这需要一个选段树或者BIT的数据结构。 + +如果遇到的是gather,那么我们就需要找到最小的行号i,满足```seats[i]>=k```.那么如何高效地实现这个功能呢?也是用线段树。我们需要一个函数,支持查询[0,row]这个区间内的最大值。我们可以通过二分法,快速查到满足条件的最小的row。那么我们就可以更新```seats[row]-=k```. + +所以,我们需要利用两种线段树的模板,分别实现查询rangeSum和rangeMax的功能。当然,也要支持节点数值的动态修改。 From 4ca41433ae81eadd1ec299d5fe397771f8731716 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: Sun, 5 Jun 2022 23:56:21 -0700 Subject: [PATCH 35/35] Update range_sum.cpp --- Template/SegmentTree/range_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Template/SegmentTree/range_sum.cpp b/Template/SegmentTree/range_sum.cpp index 4eebd6dd5..7e7ad95fe 100644 --- a/Template/SegmentTree/range_sum.cpp +++ b/Template/SegmentTree/range_sum.cpp @@ -58,7 +58,7 @@ class SegTreeNode } } - LL queryRange(int a, int b) // query the maximum value within range [a,b] + LL queryRange(int a, int b) // query the sum over range [a,b] { if (b < start || a > end ) {