所谓珂朵莉树,就是珂朵莉发明的树。
(逃
前言
在数据随机且带区间推平操作时适用,此时所有操作的期望颜色段数都是
O
(
log
n
)
O(\log n)
O(logn) 的,可以使用暴力解决即可。
暴力即优雅。
解析
利用 set
维护颜色段:
struct node{
int l,r;
ll v;
node(int L=0,int R=0,ll V=0):l(L),r(R),v(V){}
bool operator < (const node &oth)const{return l<oth.l;}
};
bool cmp(const node &x,const node &y){
return x.v<y.v;
}
set<node>s;
split
分裂出以 p p p 为左端点的颜色段,并返回迭代器。
It split(int p){
It it=s.lower_bound((node){p,0,0});
if(it!=s.end()&&(*it).l==p) return it;
it--;
if((*it).r<p) return s.end();
int l=(*it).l;
int r=(*it).r;
ll v=(*it).v;
s.erase(it);
s.insert((node){l,p-1,v});
return s.insert((node){p,r,v}).first;
}
assign
对
(
l
,
r
)
(l,r)
(l,r) 区间颜色推平。
必须先
s
p
l
i
t
(
r
+
1
)
split(r+1)
split(r+1),再
s
p
l
i
t
(
l
)
split(l)
split(l),不然可能会RE!
然而由于随机数据,RE的概率其实不大。
inline void assign(int l,int r,int w){
It itr=split(r+1),itl=split(l);
s.erase(itl,itr);
s.insert((node){l,r,w});
}