数据结构的非经典解法

1.分块(在线)

把要维护的序列分成 n 块, 每块长度 n ( 最后一块的长度为 nn2 )
对于单次区间操作:
被该区间包含的整块打上标记, 左端和右端剩余部分(小于 2n 个)直接暴力操作, 复杂度为 O(n)

代码:分块
2.莫队(离线)

对于一系列区间操作:
假设我们在已知区间 [l,r] 的答案, 在 O(f(n)) 的时间复杂度内能够得到 [l1,r],[l+1,r],[l,r1],[l,r+1] 的答案, 按照一定的顺序将操作排序, 使得在相邻的两次操作区间进行上述转移的复杂度为 g(n) , 通过暴力转移来进行操作, 时间复杂度为 O(f(n)g(n))

经典排序方法

我们利用上面的分块算法将序列分为 n 块, 当2个询问区间的左端点在同一块时, 按照右端点来排序, 否则按照左端点来排序, 不难证明完成全部转移的复杂度为 O(nn)

代码:莫队
3.cdq分治(离线)

对于多维偏序问题:
这里讨论最简单的3维偏序问题: 在三维坐标中一个点有3个属性 x,y,z , 定义点 (xi,yi,zi) 小于另外一个点 (xj,yj,zj) 当且仅当 xixj yiyj zizj , 对于每一个点回答比该点小的点的个数

先对第一维 x 进行升序排序, 并对点编号, 对于编号在[l,r]的所有点, 我们取 mid=l+r2 , 这时编号在 [l,mid] 的点的 x 坐标一定小于或等于[mid+1,r]的点, 接下来分别对编号为 [l,mid] [mid+1,r] 的点对第二维 y 进行升序排序, 对于在[mid+1,r]里面的每一个点 pi , 我们将 [l,mid] 区间中 y 坐标小于或等于pi z 坐标更新进某种数据结构(用于查询前缀和), 通过一次查询点pi z 坐标的前缀和, 便能够得到编号在[l,mid]区间中比 pi 点小的点的个数, 再递归处理 [l,mid] , [mid+1,r] ,复杂度 O(nlog2n)

代码:cdq分治
4.整体二分(离线)

对于一些列区间询问:
考虑单个询问区间为 [l,r] 的询问: 如果该询问能够在不改变原序列复杂度只和该区间的长度线性相关, 那么就可以使用整体二分来解决所有的询问
对于答案区间 [l,r] , 我们取中点 mid=l+r2 , 如果该询问的答案小于或等于 mid 那么将该询问划分到左区间, 否则划分到右区间, 递归处理左区间和右区间, 复杂度 O(nlogn)

代码:整体二分
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值