• 分块入门学习笔记


    引言:

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

    总述:

      对于一个长度为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的情况下也慢不了多少),但块内乱搞的灵活性高(例题就是给每块内都排序,线段树做得到吗),双方各有千秋吧。

  • 相关阅读:
    nuxt使用pdfjs-dist插件实现pdf预览
    package.json详细介绍
    encodeURI()和encodeURIComponent() 区别
    前端预览pdf——文件流
    fatal: unable to access 'https://github.com/xxxxx/xxxx.git/': Failed to connect to github.com port 443: Timed out
    vue分隔输入验证码
    Vue简单实现滚动到底部加载数据
    nuxt pdf在线预览
    Eclipse入门-HelloWorld
    多任务学习算法综述
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/14049123.html
Copyright © 2020-2023  润新知