当前位置: 首页 > wzjs >正文

工信部信息备案网站首页江西seo

工信部信息备案网站首页,江西seo,全球网站免费空间注册,唐山做网站公司本博客用于记录板子 1、倍增算法2、DFS序求LCA3、重链剖分 学习算法推荐: 灵茶山艾府 1、倍增算法 O ( n log ⁡ n ) O(n \log n) O(nlogn)预处理, O ( log ⁡ n ) O(\log n) O(logn)查询 讲解看:树的第K个祖先 练习题:P3379 …

本博客用于记录板子

  • 1、倍增算法
  • 2、DFS序求LCA
  • 3、重链剖分

学习算法推荐: 灵茶山艾府

1、倍增算法

O ( n log ⁡ n ) O(n \log n) O(nlogn)预处理, O ( log ⁡ n ) O(\log n) O(logn)查询

讲解看:树的第K个祖先

练习题:P3379 【模板】最近公共祖先(LCA)
直接贴下面代码会超时,这与bufio有关,换成快读就过了

代码:

package mainimport ("bufio". "fmt""math/bits""os"
)func main() {in, out := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)defer out.Flush()var n, m, s, x, y intFscan(in, &n, &m, &s)g := make([][]int, n+1) // 数据量大的时候,bufio读取数据有问题,这里最好写成5e5+1for i := 0; i < n-1; i++ {Fscan(in, &x, &y)g[x] = append(g[x], y)g[y] = append(g[y], x)}mx := bits.Len(uint(n))pa := make([][]int, n+1)for i := range pa {pa[i] = make([]int, mx)for j := range pa[i] {pa[i][j] = -1}}dep := make([]int, n+1)var dfs func(int, int)dfs = func(u, p int) {dep[u] = dep[p] + 1pa[u][0] = pfor _, ne := range g[u] {if ne == p {continue}dfs(ne, u)}}dfs(s, 0)for i := 0; i < mx-1; i++ {for x := 1; x <= n; x++ {if p := pa[x][i]; p >= 0 {pa[x][i+1] = pa[p][i]} else {pa[x][i+1] = -1}}}uptoDep := func(x, d int) int {for k := uint(dep[x] - d); k > 0; k &= k - 1 {x = pa[x][bits.TrailingZeros(k)]}return x}lca := func(x, y int) int {if dep[x] < dep[y] {x, y = y, x}x = uptoDep(x, dep[y])if x == y {return x}for i := mx - 1; i >= 0; i-- {if pa[x][i] != pa[y][i] {x, y = pa[x][i], pa[y][i]}}return pa[x][0]}for i := 0; i < m; i++ {Fscan(in, &x, &y)Fprintln(out, lca(x, y))}
}

在这里插入图片描述

2、DFS序求LCA

为什么用DFS序求LCA?
优点: O ( n log ⁡ n ) O(n \log n) O(nlogn)预处理, O ( 1 ) O(1) O(1)查询,适用于大量查询的情况

讲解看 冷门科技 —— DFS 序求 LCA

核心思想:

dfs序是按照深度优先遍历得到的序列,dfn[x]是节点x在dfs序中的下标。

对于成祖辈节点的结构来说,祖宗节点的dfn要小于子节点的dfn

对于两个节点x, y

1、如果二者形成下述格式 (旁边数字是dfn)

在这里插入图片描述

这种情况下X一定不是LCA,且dfn值在 [ d f n [ x ] , d f n [ y ] ] [dfn[x], dfn[y]] [dfn[x],dfn[y]]的节点一定在D的子树中。
考虑Y分支上D 的第一个儿子节点Z, Z的父亲节点一定是X, YLCA

进一步的, [ d f n [ x ] + 1 , d f n [ y ] ] [dfn[x] + 1, dfn[y]] [dfn[x]+1,dfn[y]]深度最小的节点的父节点一定是LCA

2、如果二者形成下述格式
在这里插入图片描述
此时X一定是X,Y的LCA, 进一步的讲, [ d f n [ x ] + 1 , d f n [ y ] ] [dfn[x] + 1, dfn[y]] [dfn[x]+1,dfn[y]]深度最小的节点的父节点一定是LCA

没有上述两个情况之外的例子。

那么问题变成了求 [ d f n [ x ] + 1 , d f n [ y ] ] [dfn[x] + 1, dfn[y]] [dfn[x]+1,dfn[y]]深度最小节点的父节点。这可以用ST表来维护

代码:

package mainimport ("bufio". "fmt""math/bits""os"
)func main() {in, out := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)defer out.Flush()var n, m, s, x, y intFscan(in, &n, &m, &s)g := make([][]int, n+1)for i := 0; i < n-1; i++ {Fscan(in, &x, &y)g[x] = append(g[x], y)g[y] = append(g[y], x)}t := bits.Len(uint(n))st := make([][]int, n+1) // st[i][j]表示 [i, i + 2^j)深度最小节点的父节点for i := range st {st[i] = make([]int, t)}clock := 0dfn := make([]int, n+1)var dfs func(int, int)dfs = func(u, p int) {clock++dfn[u] = clockst[clock][0] = pfor _, ne := range g[u] {if ne != p {dfs(ne, u)}}}dfs(s, 0)op := func(a, b int) int {if dfn[a] < dfn[b] {return a}return b}for j := 1; 1<<j <= n; j++ {for i := 1; i+1<<j <= n+1; i++ {st[i][j] = op(st[i][j-1], st[i+1<<(j-1)][j-1])}}lca := func(u, v int) int {if u == v {return u}if dfn[u] > dfn[v] {u, v = v, u}left := dfn[u] + 1right := dfn[v]d := bits.Len(uint(right+1-left)) - 1// [left, right], st右侧是开区间,所以下面是right+1return op(st[left][d], st[right+1-1<<d][d])}for i := 0; i < m; i++ {Fscan(in, &x, &y)Fprintln(out, lca(x, y))}
}

在这里插入图片描述

3、重链剖分

推荐观看:重链剖分
没有基础也不看上面推荐视频的话,下面代码是看不懂的

核心思路: 如果x, y不在同一个链上,那么让链头深度较小的节点向上跳。
如果在一个链上,返回深度较小的节点。

package mainimport ("bufio". "fmt""os"
)func main() {in, out := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)defer out.Flush()var n, m, s, x, y intFscan(in, &n, &m, &s)g := make([][]int, n+1)for i := 0; i < n-1; i++ {Fscan(in, &x, &y)g[x] = append(g[x], y)g[y] = append(g[y], x)}son, fa, dep, sz := make([]int, n+1), make([]int, n+1), make([]int, n+1), make([]int, n+1)var dfs1 func(int, int)dfs1 = func(u, p int) {dep[u] = dep[p] + 1sz[u] = 1fa[u] = pfor _, ne := range g[u] {if ne != p {dfs1(ne, u)if sz[ne] > sz[son[u]] {son[u] = ne}sz[u] += sz[ne]}}}// todo: dfn, rank在这里用不到,这里只是为了HLD的完整性dfn, top, rank := make([]int, n+1), make([]int, n+1), make([]int, n+1)clock := 0var dfs2 func(int, int)dfs2 = func(u, tp int) {clock++dfn[u] = clocktop[u] = tprank[clock] = uif son[u] == 0 {return}dfs2(son[u], tp)for _, ne := range g[u] {if ne == fa[u] || ne == son[u] {continue}dfs2(ne, ne) // 新开一个作为链头}}dfs1(s, 0)dfs2(s, s)lca := func(x, y int) int {for top[x] != top[y] {// 保证x所在链头是深度较大的if dep[top[x]] < dep[top[y]] {x, y = y, x}x = fa[top[x]]}// 在同一条链上if dep[x] < dep[y] {return x}return y}for i := 0; i < m; i++ {Fscan(in, &x, &y)Fprintln(out, lca(x, y))}
}

运行结果:
在这里插入图片描述

http://www.dtcms.com/wzjs/317446.html

相关文章:

  • 做购物平台网站客户体验活动搭建个人网站
  • 青岛知名网站建设公司免费推广网站
  • 怎样做网站店铺cilimao磁力猫在线搜索
  • 利用百度网盘自动播放做视频网站如何在百度发布广告信息
  • 网站开发工具的选择2023年的新闻时事热点论文
  • 做有奖竞猜网站违法吗青岛官网seo方法
  • 沅江市住房和建设局网站外贸建站与推广如何做
  • b2b网站怎么做网页友情链接
  • 不允许做企业网站seo搜索引擎优化到底是什么
  • wordpress站点维护百度产品推广怎么收费
  • 做网站还是微信小程序成都疫情最新消息
  • 班级网站制作建设的设计和作用seo搜索引擎优化教程
  • 建设银行 网站无法打开草根站长工具
  • 淘宝网官方网站网页版深圳做网站公司哪家好
  • 韩国美食做视频网站谷歌浏览器下载
  • 济南制作网站的公司营销型网站建设运营
  • 谁有网站推荐一下好中国十大互联网公司
  • 图片网站的优化手机游戏性能优化软件
  • 网站做游戏吗旺道seo推广
  • 建筑工地网站有哪些seo比较好的优化方法
  • 网站建设四段合一上海百度关键词推广
  • 做外贸零售和批发批发网站外贸独立站推广
  • 网站建设英文seo咨询茂名
  • 免费做电子书的网站百度seo搜索营销新视角
  • 关于做膳食的一些网站绍兴seo推广公司
  • 个人能否做网站徐州seo培训
  • 怎样在微信里做网站东莞网站定制开发
  • 大数据软件和网站开发那个就业好高权重网站出售
  • 长沙网站排名方案怎样看网页的友情链接
  • 武汉google网站制作建网站需要什么条件