图论学习十之Sparse table

Posted mary-sue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论学习十之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])];

 

以上是关于图论学习十之Sparse table的主要内容,如果未能解决你的问题,请参考以下文章

学习:图论----一般图

图论学习

图论学习一之basic

图论 —— tarjan 缩点 割点 (学习历程)

图论的小总结

图论学习二之Topological Sort(拓扑排序)