zoukankan      html  css  js  c++  java
  • 图论学习十之Sparse table

    ST表

           无修改区间最值询问问题

    给出一个数组a[1..N]

    Q个询问,每次询问每次询问区间[x,y]最大值。

    N,Q <= 100000

     

            St表的递推


    st[k][i]表示从i开始连续2^k个元素的最值。

    得出递推式

      • st[k+1][i]=max(st[k][i], st[k][i+2^k]);(假设求最大值)

    从小到大枚举k,再枚举i

    那么预处理出上面这个数组的复杂度为O(nlogn)

     

            询问操作


    找出最大的k使得 2^k<=y-x+1

    注意到[x,x+2^k-1], [y-2^k+1,y]两个子区间覆盖原区间[x,y]

    那么答案就是max(st[k][x], st[k][y-(2^k)+1]).

    •  k= log(y-x+1) 向下取整

    小技巧:内建函数计算log
      • #define log(x) (31-__builtin_clz(x))

    有用的性质
      • 求多个数最大值时,同一个值重复出现多次和出现次效果是相同的

     

    St表主要运用于在没有修改的情况需要能快速求解区间最值的情况。

     

            Sparse table 时间复杂度


    预处理: O(nlogn)

    每次询问: O(1)

     

            LCA


    给定一棵树。

    Q个询问,每次询问某两个点(x,y)的最近公共祖先

     

    考虑两个相同深度的节点的lca


    如果同时往上走k步到达相同节点,则往上走k+1步仍然相同


    for(int k=20;k>=0;k--)

      • if (st[x][k] != st[y][k]) x = st[x][k], y=st[y][k];

    lca=fa[x]=fa[y];

     

    对于深度不同的节点,可先将深度大的往上走到深度相同


    小技巧:内建函数计算log

      • #define log(x) (31-__builtin_clz(x))


    If (dep[x]<dep[y]) swap(x,y);

    while (dep[x] > dep[y])      x = st[x][log(dep[x]-dep[y])];


    如果你不开心,那我就把右边这个帅傻子分享给你吧,
    你看,他这么好看,跟个zz一样看着你,你还伤心吗?
    真的!这照片盯上他五秒钟就想笑了。
    一切都会过去的。
    时间时间会给你答案2333
  • 相关阅读:
    C# WinForm界面上实现按条件检索数据
    DevExpress中XtraEditors.RadioGroup 控件如何保存获取选中的值及读取数据库中的值
    在QTP Test中利用vbs和cmd实现重新启动QTP
    VBS操作Excel的一点问题总结
    利用vbs维护qtp的虚拟对象的坐标
    Smoke Test和BVT Test的区别
    小结一下VS2012新开发环境的设置经历
    关闭EF4.x Code First的级联删除Cascade Delete
    关于Entity Framework 4.0/4.1数据验证的一点体会
    CentOS 6.3 Minimal yum 安装 PostgreSQL 9.2.3
  • 原文地址:https://www.cnblogs.com/Mary-Sue/p/9345817.html
Copyright © 2011-2022 走看看