【cdq分治】cdq分治与整体二分学习笔记Part1.整体二分

之所以把cdq分治和整体二分放在一起学习,是因为他们两个实在太像了…不管是做法还是代码…
感觉整体二分可能会比cdq分治稍微简单那么一点点?所以先学整体二分.
整体二分是对答案进行二分,其具体操作如下:
(比如以ZJOJ2013K大数查询为例)

具体过程

Step1.从(L,R)二分答案.mid=(L+R)>>1,用线段树维护原序列中(a,b)位置比mid大的数有多少个,同时记录对序列的操作分别是什么操作.
Step2.执行给定操作.
1.如果操作是插入,比如在a,b位置之间每个数后插入一个数c
①如果c > mid就在线段树的(a,b)部分加一,然后修改操作标记为1;
②如果c < mid,修改操作标记为0;
2.如果操作是查询,如果线段树(a,b)段的和大于c,那么答案必定比mid大,修改操作标记为1,否则操作标记为0.
Step3.进入下一层.所有标记为0的,分入区间(L,mid),标记为1的分入区间(mid+1,R).(这里重新划分后要再排序.可以归并(当然效率很高),不过直接sort也可以的.)
直到二分到L==R,L即为所求答案.
每次二分到新的答案,我们要直接清空线段树.(在根节点打清空标记,否则区间太大用memset会炸掉)
与当前访问区间不相交的另一段区间,其实始终对我们二分的答案有影响,只要记录一下这个影响就可以了,所以不需要去考虑它.

所以我们可以看出来,整体二分就是不断对数列进行划分,划分的标准就是数值的大小.因此其复杂度也是与数列长度正相关的.
时间复杂度的证明可以看2013年国家集训队论文许昊然《浅谈数据结构题的几个非经典解法》
如果您不想翻论文,我很贴心的把那一段证明引用到下面来(其实为了加深理解下面这些我都手打了):

定义T(C,S)表示待二分区间长度为C,待二分序列长度为S,不妨设单次处理时间复杂度 O(f(n)) 则有
T(C,S)=T( C2 , S0 +T( C2 ,S- S0 ))+O(f(s))
解之得 T(C,n) O(f(n)log C)
注,与上文一样该证明只有在 O(f(n))O(n) 时成立.

具体题目后面单独写题解.(你问我为什么不像别人一样把题解当例题写着里面?我要刷访问量和文章量啊233)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值