@@ -434,15 +434,58 @@ template <size_t Capacity> class point_set {
434
434
obj = tmp;
435
435
// std::swap(*it, obj);
436
436
437
+ used++;
438
+ return out;
439
+ }
440
+ }
441
+ constexpr bool can_merge (point lhs, point rhs) noexcept {
442
+ point expanded_lhs = lhs;
443
+ // expand ranges by 1 in each direction
444
+ expanded_lhs.low -= (expanded_lhs.low > INT64_MIN) ? 1 : 0 ;
445
+ expanded_lhs.high += (expanded_lhs.high < INT64_MAX) ? 1 : 0 ;
446
+
447
+ point expanded_rhs = rhs;
448
+ expanded_rhs.low -= (expanded_rhs.low > INT64_MIN) ? 1 : 0 ;
449
+ expanded_rhs.high += (expanded_rhs.high < INT64_MAX) ? 1 : 0 ;
450
+ // for example [1,5] and [6,9] can merge into [1,9]
451
+ return (expanded_lhs.low <= rhs.high && rhs.low <= expanded_lhs.high ) ||
452
+ (expanded_rhs.low <= lhs.high && lhs.low <= expanded_rhs.high );
453
+ }
454
+ constexpr point* insert_and_merge_point (int64_t position, int64_t other) {
455
+ point obj{ position, other };
456
+ auto it = lower_bound (obj);
457
+ if (it == end ()) {
458
+ *it = obj;
459
+ used++;
460
+ return it;
461
+ } else {
462
+ auto out = it;
463
+ // good chance we can merge here
464
+ if (can_merge (*it, obj)) {
465
+ // merge the points together vs inserting
466
+ it->low = it->low < obj.low ? it->low : obj.low ;
467
+ it->high = it->high > obj.high ? it->high : obj.high ;
468
+ return out;
469
+ }
470
+ auto e = end ();
471
+ while (it != e) {
472
+ auto tmp = *it;
473
+ *it = obj;
474
+ obj = tmp;
475
+ it++;
476
+ }
477
+ auto tmp = *it;
478
+ *it = obj;
479
+ obj = tmp;
480
+
437
481
used++;
438
482
return out;
439
483
}
440
484
}
441
485
public:
442
486
constexpr point_set () { }
443
487
constexpr void insert (int64_t low, int64_t high) {
444
- insert_point (low, high);
445
- // insert_point(high, low);
488
+ insert_and_merge_point (low, high);
446
489
}
447
490
constexpr bool check (int64_t low, int64_t high) {
448
491
for (auto r: *this ) {
0 commit comments