CDQ分治

前言

十几天前学了CDQ分治,总是忘记。今日恰巧有空,写博客加强记忆。
据说CDQ是发明这个算法的某位巨学。

优点

替代主席树等高级数据结构,降低常数,提高算法效率和稳定性,提高代码可靠性。

缺点

只能离线,碰到在线操作就不能使用。

基本思想

1.我们给定一系列问题,包括修改和查询某个数列。可以把这些问题排成序列,用区间 [ L , R ] [L,R] [L,R]表示。
2.分:递归处理子问题,分为左边区间 [ L , m i d ] [L, mid] [L,mid]和右边区间 [ m i d + 1 , R ] [mid+1, R] [mid+1,R]处理。
3.治:合并子问题,计算左边区间对右边区间的影响。

简单到炸是不是

基本应用

给定一个N个元素的序列a,初始值全部为0,对这个序列进行以下两种操作:
操作1:格式为1 x k,把位置x的元素加上k(位置从1标号到N)。
操作2:格式为2 x y,求出区间[x,y]内所有元素的和。

这是一个二维偏序问题,虽然可以用树状数组做。

每个操作用一个有序对(a,b)表示,其中a表示操作到来的时间,b表示操作的位置。
时间是默认有序的,所以我们在合并子问题的过程中,就按照b从小到大的顺序合并。
我们定义结构体Query包含3个元素:type,idx,val,其中idx表示操作的位置,type为1表示修改,val表示“加上的值”。
而对于查询,我们用前缀和的思想把他分解成两个操作:sum[1,y]-sum[1,x-1],
即分解成两次前缀和的查询。在合并的过程中,
type为2表示遇到了一个查询的左端点x-1,
需要把该查询的结果减去当前“加上的值的前缀和”,type为3表示遇到了一个查询的右端点y,
需要把查询的结果加上当前“加上的值的前缀和”,val表示“是第几个查询”。这样,我们就把每个操作转换成了带有附加信息的有序对(时间,位置),
然后对整个序列进行CDQ分治

——摘自这里

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值