Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
insert_reverse_array.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2
4 template<typename Node>
5 struct RBSTBase {
6 using Ptr=Node*;
7 template<typename...Args>
8 inline Ptr my_new(Args...args) { return new Node(args...); }
9 inline void my_del(Ptr t) { delete t; }
10 inline Ptr make_tree()const { return nullptr; }
11 int size(Ptr t)const { return count(t); }
12 Ptr merge(Ptr l, Ptr r) {
13 if(!l||!r) return l?l:r;
14 if(int((rng()*(l->cnt+r->cnt))>>32)<l->cnt) {
15 push(l);
16 l->r=merge(l->r,r);
17 return update(l);
18 }else {
19 push(r);
20 r->l=merge(l,r->l);
21 return update(r);
22 }
23 }
24 pair<Ptr,Ptr> split(Ptr t, int k) {
25 if(!t) return {nullptr,nullptr};
26 push(t);
27 if(k<=count(t->l)) {
28 auto s=split(t->l,k);
29 t->l=s.second;
30 return {s.first,update(t)};
31 }else {
32 auto s=split(t->r,k-count(t->l)-1);
33 t->r=s.first;
34 return {update(t),s.second};
35 }
36 }
37 Ptr build(int l, int r, const vector<decltype(Node::key)>& v) {
38 if(l+1==r) return my_new(v[l]);
39 int m=(l+r)>>1;
40 Ptr pm=my_new(v[m]);
41 if(l<m) pm->l=build(l,m,v);
42 if(m+1<r) pm->r=build(m+1,r,v);
43 return update(pm);
44 }
45 Ptr build(const vector<decltype(Node::key)>& v) {
46 return build(0,(int)v.size(),v);
47 }
48 template<typename...Args>
49 void insert(Ptr& t, int k, const Args& ...args) {
50 auto x=split(t,k);
51 t=merge(merge(x.first,my_new(args...)),x.second);
52 }
53 void erase(Ptr& t, int k) {
54 auto x=split(t,k);
55 auto y=split(x.second,1);
56 my_del(y.first);
57 t=merge(x.first,y.second);
58 }
59
60 protected:
61 static uint64_t rng() {
62 static uint64_t x_=88172645463325252ULL;
63 return x_^=x_<<7,x_^=x_>>9,x_&0xFFFFFFFFull;
64 }
65 inline int count(const Ptr t) const { return t?t->cnt:0; }
66 virtual void push(Ptr)=0;
67 virtual Ptr update(Ptr)=0;
68 };
69
70 template<typename T, typename E>
75 int cnt;
76 bool rev;
77 LazyReversibleRBSTNode(const T& t=T(), const E& e=E()):l(),r(),key(t),sum(t),lazy(e),cnt(1),rev(false) {}
78 };
79
80 template<typename T, typename E, T(*f)(T,T), T(*g)(T,E), E(*h)(E,E), T(*ts)(T)>
82 using Node=LazyReversibleRBSTNode<T,E>;
84 using base::merge;
85 using base::split;
86 using typename base::Ptr;
88 void toggle(Ptr t) {
89 if(!t)return;
90 swap(t->l,t->r);
91 t->sum=ts(t->sum);
92 t->rev^=true;
93 }
94 T fold(Ptr&t, int a, int b) {
95 auto x=split(t,a);
96 auto y=split(x.second,b-a);
97 auto ret=sum(y.first);
98 t=merge(x.first,merge(y.first,y.second));
99 return ret;
100 }
101 void reverse(Ptr&t, int a, int b) {
102 auto x=split(t,a);
103 auto y=split(x.second,b-a);
104 toggle(y.first);
105 t=merge(x.first,merge(y.first,y.second));
106 }
107 void apply(Ptr&t, int a, int b, const E&e) {
108 auto x=split(t,a);
109 auto y=split(x.second,b-a);
110 propagate(y.first,e);
111 t=merge(x.first,merge(y.first,y.second));
112 }
113
114 protected:
115 inline T sum(const Ptr t)const {return t?t->sum:T();}
116 Ptr update(Ptr t)override {
117 push(t);
118 t->cnt=1;
119 t->sum=t->key;
120 if(t->l)t->cnt+=t->l->cnt,t->sum=f(t->l->sum,t->sum);
121 if(t->r)t->cnt+=t->r->cnt,t->sum=f(t->sum,t->r->sum);
122 return t;
123 }
124 void push(Ptr t)override {
125 if(t->rev) {
126 if(t->l)toggle(t->l);
127 if(t->r)toggle(t->r);
128 t->rev=false;
129 }
130 if(t->lazy!=E()) {
131 if(t->l)propagate(t->l,t->lazy);
132 if(t->r)propagate(t->r,t->lazy);
133 t->lazy=E();
134 }
135 }
136 void propagate(Ptr t, const E& x) {
137 t->lazy=h(t->lazy,x);
138 t->key=g(t->key,x);
139 t->sum=g(t->sum,x);
140 }
141 };
142 template<typename T>
143 T op(T a, T b) { return a+b; }
144 template<typename T>
145 T e(T a) { return a; }
146} // namespace InsertableReversibleArrayImpl
147
148/// @file insert_reverse_array.hpp
149/// @brief 挿入・削除・区間反転可能な配列
150/// @ref https://nyaannyaan.github.io/library/rbst/lazy-reversible-rbst.hpp.html
151template<typename T>
154 using node_ptr=node*;
155 node_ptr root;
157 T,
158 T,
164 int _size=0;
165
166 int size() {
167 return _size;
168 }
169
171
173 vector<T>init(n);
174 root=rbst.build(init);
175 _size=n;
176 }
177
178 InsertableReversibleArray(const vector<T>&init) {
179 root=rbst.build(init);
180 _size=init.size();
181 }
182
183 /// @brief i 番目に x を挿入する
184 void insert(int k, T x) {
185 assert(0<=k&&k<=_size);
186 _size++;
187 rbst.insert(root,k,x);
188 }
189
190 /// @brief i 番目を削除する
191 void erase(int k) {
192 assert(0<=k&&k<_size);
193 _size--;
194 rbst.erase(root,k);
195 }
196
197 /// @brief i 番目の要素を取得する
198 T get(int k) {
199 assert(0<=k&&k<_size);
200 return rbst.fold(root,k,k+1);
201 }
202
203 /// @brief i 番目の要素を x に変更する
204 void set(int k, T x) {
205 assert(0<=k&&k<_size);
206 erase(k);
207 insert(k,x);
208 }
209
210 /// @brief 区間 [l, r) の要素を反転する
211 void reverse(int l, int r) {
212 assert(0<=l&&l<=r&&r<=_size);
213 rbst.reverse(root,l,r);
214 }
215};
InsertableReversibleArray(const vector< T > &init)
void set(int k, T x)
i 番目の要素を x に変更する
T get(int k)
i 番目の要素を取得する
InsertableReversibleArrayImpl::LazyReversibleRBST< T, T, InsertableReversibleArrayImpl::op< T >, InsertableReversibleArrayImpl::op< T >, InsertableReversibleArrayImpl::op< T >, InsertableReversibleArrayImpl::e< T > > rbst
void erase(int k)
i 番目を削除する
InsertableReversibleArray()=default
void insert(int k, T x)
i 番目に x を挿入する
void reverse(int l, int r)
区間 [l, r) の要素を反転する
void insert(Ptr &t, int k, const Args &...args)
Ptr build(const vector< decltype(Node::key)> &v)
Ptr build(int l, int r, const vector< decltype(Node::key)> &v)