zoukankan      html  css  js  c++  java
  • 分块入门学习笔记

    引言:

      对于区间问题,暴力算法(一个点一个点跳)的复杂度太高,尝试优化。可以将一些点“捆绑起来”,记录一下整体的贡献/维护信息,这样跳的时候就可以一块块跳,复杂度有很大优化。

    总述:

      对于一个长度为n的序列,我们可以按照一个固定的长度m,顺序将序列分成n/m+(n%m>0?1:0) 组。对于每组,我们可以进行一点处理,维护出该组的整体贡献。这样询问到包含这组的区间时,我们可以直接返回该组的整体贡献信息而非暴力查询该组的每一点;修改包含这组的区间时,可以通过打标记的方式,减少复杂度。

    分析时间复杂度(块的数量与n/m同规模,为了方便,下文将n/m看做与块的数量 相等):

      预处理:O(n)分块,n/m个块,若给每个块做O(x)的处理,知总复杂度:

        O(n+n/m *x)

      区间操作:

        若该组的整体贡献可以通过维护信息O(k)得出,对于区间完整包含的块,最多有n/m个块,对每个块O(k)求出整体贡献。对区间不完整包含的块(区间左端、右端),最多有2块,2m个点,暴力枚举单点处理,设枚举一个点进行处理的复杂度为O(y)。知一次操作的复杂度:

        O(n/m*k+ m*y)

      综上,设有w个操作,则总复杂度:O(n+n/m*x+w*(n/m*k+ m*y))。一般取x=w=n,k=y=1,则总复杂度相当于O(n(n/m+m)) 由均值不等式知取m=sqrt(n)时复杂度最小,为O(nsqrt(n))。故块的大小常常取sqrt(n)。

    例题:loj#6279. 数列分块入门 3

    (开o2才能满分的正解。。。)

    题解参考大佬博客

    总结:

      当问题可以分解(或说可由小区间合并得到答案)时,可用线段树或分块做。

        但线段树的树形结构有时候会约束它的使用,例如单点修改时要额外修改该点到根路径上的所有点,导致在线段树节点中能乱搞的力度不如分块大。

          (树套树:“论单点乱搞力度谁有我大?“

            (捂嘴)

           分块:“闭嘴吧你,可不看看你那代码不下400行都写不完”)

        分块虽然时间复杂度略逊一筹(n=1e5的情况下也慢不了多少),但块内乱搞的灵活性高(例题就是给每块内都排序,线段树做得到吗),双方各有千秋吧。

  • 相关阅读:
    Ubuntu18.04安装NAVIDIA驱动
    ubuntu 设置root用户密码并实现root用户登录
    配置ubuntu允许远程SSH连接
    Centos7安装yum命令
    NVDIA往期在线研讨会地址 论坛提问地址
    二进制安装单master节点测试环境k8s集群
    kubeadm初始化k8s-延长证书过期时间
    kubeadm初始化k8s-删除控制节点-重新把控制节点加入集群步骤
    kubeadm安装的多master节点的k8s高可用集群
    二进制安装多master节点的k8s集群
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/14049123.html
Copyright © 2011-2022 走看看