珂朵莉树(ODT)

珂朵莉树 ODT

主要内容

珂朵莉树是基于数据随机且有整体赋值操作而对序列操作的乱搞算法。

它的主要思想是用 set 维护若干个数值上相同的区间,并暴力处理其他询问。

建立

set 中,我们需要用结构体记录每个区间的信息:

struct NODE
{
	 int l,r;
	 mutable ll val; // mutable 表示可变的,便于在外边修改 val 的值
	 NODE(int L,int R=-1,ll Val=0):l(L),r(R),val(Vol){} // 相当于 (NODE){l,r,val}
	 bool friend operator < (NODE x,NODE y) { return x.l<y.l; } // 重载 <
};
set<NODE> s;

这样再 set 中就可以自动按照左端点排序了,注意在初始化的时候加入 \([n+1,n+1]\) 的区间。

split

珂朵莉树用 split 操作分裂出一堆区间后暴力操作。

inline auto split(int p)
{
	 auto it=s.lower_bound(NODE(p));
	 if(it!=s.end() && it->l==p) return it;
	 it--;
	 int l=it->l,r=it->r;
	 ll v=it->val;
	 s.erase(it);
	 s.insert(NODE(l,p-1,v));
	 return s.insert(NODE(p,r,v)).fi;
}

assign

如果只有 split 操作那 set 中元素岂不是爆炸?我们需要时不时将一些区间合并为一个区间才能保证复杂度。

\(\bigstar\texttt{attention}\):在推平的时候需要先 split 右端点再左端点,否则会 RE!

inline void assign(int l,int r,int v)
{
	 auto itr=s.split(r+1),itl=s.split(l);
	 s.erase(itl,itr); // 用将 [itl,itr) 之间的元素全部删除
	 s.insert(NODE(l,r,v));
}

其他操作

其他操作就可以直接暴力在 set 中搞了,下面以求区间内每个数的平方的和为例:

inline ll query(int l,int r)
{
	 auto itr=s.split(r+1),itl=s.split(l);
	 ll ret=0;
	 for(auto it=itl;it!=itr;it++)
	 	 ret+=1ll*(it->r-it->l+1)*it->v*it->v;
	 return ret;
}

复杂度

如果只有推平操作,即不需要将这个区间拎出来暴力处理,复杂度是 \(\mathcal{O(n\log n)}\)

如果有区间加等操作,就要基于数据随机了,这种情况下一定时间内进行一次推平可以达到 \(\mathcal{O(m\log n)}\) 的复杂度。

例题

起源题:CF896C Willem, Chtholly and Seniorious

CF1638E Colorful Operations

在询问的时候把答案累加上去,再套上一个树状数组利用前缀和维护区间加即可。

CF1423G Growing flowers

给你一个序列,支持以下两种操作:

  • 区间推平,即将 \([l,r]\) 中的数都改为同一个数 \(x\)
  • 求序列中所有长度为 \(k\) 的子段中不同数的个数的和。

\(n,q\le 10^5\)

MatrixCascade:这题 800。

区间推平,所以考虑珂朵莉树。发现如果每次询问的时候再去统计,复杂度至少是和区间个数同阶,不可取。

考虑在推平的过程中更新答案。

将即将被推平的区间拎出来,将他们对答案减小的贡献减去。

对每一种数建立一个 set,再用线段树记录方案数即可。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值