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

工信部信息备案网站首页万能引流软件

工信部信息备案网站首页,万能引流软件,现在流行的网站开发制作工具,合肥网站制作价格本博客用于记录板子 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/433639.html

相关文章:

  • 如何规划企业网络推广方案需要优化的网站有哪些?
  • 无锡微信网站开发seo怎么发布外链
  • 做网站时的兼容问题上海百度推广
  • 宁夏政府采购网东莞网络优化公司
  • 期货交易网站开发域名网站查询
  • 网站建设分金手指排名四广州seo网站推广公司
  • c 网站开发 书百度推广平台登录网址
  • 自适应手机网站 css优化网站平台
  • 门头沟新乡网站建设seo文章优化方法
  • asp.net 做网站实例如何推广引流
  • 用自己电脑做服务器 网站seo广告优化多少钱
  • 设计师服务平台卡密号网站seo推广员招聘
  • 如何做单页网站网推怎么做
  • 盐城市城乡建设局网站建站宝盒
  • 盐山县招聘网站建设代运营公司
  • 网站改版 打造企业文化郑州网站seo优化公司
  • 代做网页设计作业价格厦门seo外包公司
  • 企业网站备案好不好百度商务合作联系
  • 导航网站怎么做的四川seo技术培训
  • wordpress网站关键字seo搜索引擎优化5
  • 网站上传空间的ip地址自动点击关键词软件
  • 杭州专业做网站的网站网络推广运营
  • 有了域名如何建网站seo赚钱方式
  • 网站服务器端口设置网站关键词推广工具
  • godaddy网站建设教程小程序开发一个多少钱啊
  • 哈尔滨百姓网免费发布信息徐州seo
  • 怎么做百度联盟网站百度搜索指数入口
  • 建站模板工程造价十大搜索引擎网站
  • 自适应网站的缺点关键词推广排名
  • 前端用什么框架做网站瑞金网络推广