Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
range_set.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
3/// @brief 区間を set で管理するデータ構造
4/// @ref verify:https://yukicoder.me/submissions/1021763
5struct RangeSet {
8 dat.insert({-INFL,-INFL});
9 dat.insert({INFL,INFL});
10 }
11
12 /// @brief 区間 [l, r) を追加する
13 void insert(ll l, ll r) {
14 assert(l<r);
15 auto it=dat.lower_bound({l,0});
16 if(it!=dat.begin()) {
17 it--;
18 if(it->second>=l) {
19 l=it->first;
20 r=max(r,it->second);
21 it=dat.erase(it);
22 } else {
23 it++;
24 }
25 }
26 while(it!=dat.end()&&it->first<=r) {
27 r=max(r,it->second);
28 it=dat.erase(it);
29 }
30 dat.insert({l,r});
31 }
32
33 /// @brief 区間 [l, r) を削除する
34 void erase(ll l, ll r) {
35 assert(l<r);
36 auto it=dat.lower_bound({l,0});
37 if(it!=dat.begin()) {
38 it--;
39 if(it->second>l) {
40 ll L=it->first,R=it->second;
41 it=dat.erase(it);
42 if(L<l) dat.insert({L,l});
43 if(r<R) dat.insert({r,R});
44 }else{
45 it++;
46 }
47 }
48 while(it!=dat.end()&&it->first<r) {
49 ll L=it->first,R=it->second;
50 it=dat.erase(it);
51 if(L<l) dat.insert({L,l});
52 if(r<R) dat.insert({r,R});
53 }
54 }
55
56 /// @brief 区間 [l, r) が完全に被覆されているかどうかを判定する
57 /// @attention unverified
58 bool is_covered(ll l, ll r) {
59 auto it=dat.upper_bound({l,INFL});
60 if(it==dat.begin()) return false;
61 it--;
62 return it->first<=l&&r<=it->second;
63 }
64
65 /// @brief 点 x を含む区間を返す
66 /// @brief 存在しない場合は `{-INFL, -INFL}` を返す
68 if(!is_covered(x,x+1)) return{-INFL,-INFL};
69 auto it=dat.upper_bound({x,INFL});
70 it--;
71 return*it;
72 }
73};
区間を set で管理するデータ構造 verify:https://yukicoder.me/submissions/1021763
Definition range_set.hpp:5
pair< ll, ll > covering_range(ll x)
点 x を含む区間を返す
Definition range_set.hpp:67
void insert(ll l, ll r)
区間 [l, r) を追加する
Definition range_set.hpp:13
void erase(ll l, ll r)
区間 [l, r) を削除する
Definition range_set.hpp:34
bool is_covered(ll l, ll r)
区間 [l, r) が完全に被覆されているかどうかを判定する
Definition range_set.hpp:58
set< pair< ll, ll > > dat
Definition range_set.hpp:6
const ll INFL
Definition template.hpp:13