首页 > 其他分享 >长链剖分 入门

长链剖分 入门

时间:2024-10-21 17:00:10浏览次数:5  
标签:长链 入门 剖分 dep tp son int mxd

长链剖分

额,其实和树剖差不多,对于每个节点 \(u\) 维护 \(mxd_u\) 为子树内节点深度最大值。

那么令 \(Son(u)\) 里取到 \(mxd_v\) 最大的儿子 \(v\) 为长儿子,类似重链剖分处理即可。

同样令连接不同长链的两个点之间的边为虚边。

有如下性质:

  • 从根到节点 \(u\),所经过虚边个数不超过 \(O(\sqrt n)\),这是因为从 \(u\) 开始往上走,所走到的每一条长链其长度都是严格长于当前长链的,即使 \(mxd\) 相同,往上走的那条链至少还会加上父亲,这告诉我们走到根,所有的长链最多也就是 \(1+2+3……\le n\)
  • 每条链底是叶子,且是子树内最深节点
  • 节点 \(u\) 的 \(k\) 级祖先所在长链长度不小于 \(k\)。

\(O(n\log n)-O(1)\) 树上 \(k\) 级祖先

我们先利用倍增预处理出 \(f_{u,i}\) 为 \(u\) 的 \(2^i\) 级祖先,\(lg_i=\lfloor\log_2(i)\rfloor\)

查询 \(u\) 的 \(k\) 级祖先,先查 \(x=f_{u,lg_k}\),\(k'=k-2^{lg_k}\)

这样就满足 \(x\) 所在长链长度 \(>k'\)。

我们对于每个链,维护从链顶往上走 \(0\sim len\) 和往下走 \(0\sim len\) 的节点,就可以分类讨论 \(dep_x-dep_{top_x}\) 与 \(k'\) 的大小关系找到 \(k\) 级祖先了

在存储时,我们可以类似树剖进行 \(dfn\) 重标号,将 \(u\) 存下 \(top_u\) 往上走 \(dep_u-dep_{top_u}\) 步的节点。

void dfs(int u,int fa){
    f[u][0]=fa;dep[u]=dep[fa]+1;mxd[u]=dep[u];
    for(int i=1;i<=19;++i)f[u][i]=f[f[u][i-1]][i-1];
    for(auto v:e[u])if(v!=fa){
        dfs(v,u);if(mxd[v]>mxd[u])son[u]=v,mxd[u]=mxd[v];
    }
}
void dfs2(int u,int tp,int lt){
    dfn[u]=++idx;down[idx]=u;up[idx]=lt;top[u]=tp;
    if(!son[u])return ;
    dfs2(son[u],tp,f[lt][0]);
    for(auto v:e[u])if(v!=f[u][0]&&v!=son[u])dfs2(v,v,u);
}
int get(int x,int k){
    if(!k)return x;
    x=f[x][lg[k]];
    k-=1ll<<lg[k];
    int d=dep[x]-dep[top[x]];
    if(d>=k)return down[dfn[x]-k];
    return up[dfn[top[x]]+k-d-1];
}

优化 dp

长链剖分可以优化 维护仅与深度有关的一个信息 的 dp。

例如子树内深度为 \(k\) 的节点个数/子树内深度出现次数众数等。

一般形式是设 \(dp_{u,k}\) 为子树内深度取 \(k\) 的答案。

在 dp 时采用 dfs 形式,设当前是 \(dfs(u,tp)\),我们遵循以下步骤:

  • 若 \(u=tp\),开一个 vector 长度为 \(mxd_u-dep_u+1\) 存储每个深度 \(-dep_{tp}\) 的 dp 值。
  • 优先递归长儿子
  • 递归非长儿子,并暴力合并信息(枚举长儿子第二维 \(j\) 并找到在 \(dp_{tp}\) 的相应位置进行更新)
  • 加入点 \(u\) 的信息
  • 统计答案

注意到存储的时候有个 \(dep_{tp}\) 的下标偏移。

模板:求各个点子树内各个节点深度的众数。

void dfs2(int u,int tp){
    if(u==tp)f[u].resize(mxd[u]-dep[u]+1);
    if(son[u])dfs2(son[u],tp);
    for(auto v:e[u])if(v!=lt[u]&&v!=son[u]){
        dfs2(v,v);
        for(int i=0;i<f[v].size();++i){
            f[tp][i-dep[tp]+dep[v]]+=f[v][i];
            if(f[tp][i-dep[tp]+dep[v]]>mx[tp]||(f[tp][i-dep[tp]+dep[v]]==mx[tp]&&i-dep[tp]+dep[v]<id[tp]))mx[tp]=f[tp][i-dep[tp]+dep[v]],id[tp]=i-dep[tp]+dep[v];
        }
    }
    f[tp][dep[u]-dep[tp]]++;
    if(f[tp][dep[u]-dep[tp]]>mx[tp]||f[tp][dep[u]-dep[tp]]==mx[tp]&&dep[u]-dep[tp]<id[tp])mx[tp]=f[tp][dep[u]-dep[tp]],id[tp]=dep[u]-dep[tp];
    ans[u]=id[tp]-dep[u]+dep[tp];
    // cout<<"dfs2 "<<u<<' '<<mx[tp]<<" "<<id[tp]<<"\n";
}

标签:长链,入门,剖分,dep,tp,son,int,mxd
From: https://www.cnblogs.com/spdarkle/p/18489838

相关文章

  • webpack入门一篇
    1、webpack生命周期Webpack构建过程是生命周期的概念,主要包括以下几个阶段:1.1:初始化从配置文件和shellarguments读取参数,初始化Compiler对象。根据配置文件中的entry,确定构建的入口文件。1.2:配置解析配置文件,合并shellarguments和plugin定义的默认配置,得到最终配置。......
  • 【算法】树链剖分
    1.算法简介树链剖分为将树分割成若干条链,维护树上信息的思想。通常将其分为链后能用数据结构维护。树链剖分分为重链剖分,长链剖分,实链剖分。通常重链剖分最常用,本文主要介绍重链剖分。重链剖分可将树划分为一个个长度不超过\(O(\logn)\)的链,并且保证每条链内的\(dfs\)序......
  • 零基础入门转录组下游分析——数据处理(TCGA数据库)
    零基础入门转录组下游分析——数据处理(TCGA数据库)目录零基础入门转录组下游分析——数据处理(TCGA数据库)1.数据集获取2.数据处理(Rstudio)TCGA应该是肿瘤数据最权威的来源之一,但是从TCGA上下载数据集相对来说比较麻烦,因此出现了很多针对TCGA数据进行二次开发的衍生......
  • 【Linux从入门到精通三】Linux目录结构与基础命令详解
    个人名片......
  • 【Linux从入门到精通四】基础命令详解:cd、pwd、mkdir、文件操作与管道符
    个人名片......
  • 入门网络安全工程师要学习哪些内容
        大家都知道网络安全行业很火,这个行业因为国家政策趋势正在大力发展,大有可为!但很多人对网络安全工程师还是不了解,不知道网络安全工程师需要学什么?知了堂小编总结出以下要点。网络安全工程师是一个概称,学习的东西很多,具体学什么看自己以后的职业定位。如果你以后想成......
  • 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了
       这篇文章没有什么套路。就是一套自学理论和方向,具体的需要配合网络黑白去学习。毕竟是有网络才会有黑白!有自学也有培训!1.打死也不要相信什么分分钟钟教你成为大黑阔的,各种包教包会的教程,就算打不死也不要去购买那些所谓的盗号软件之类的东西。2,我之前让你们在没有目......
  • 用人话讲计算机:小白版Python篇!(一)入门知识点和基本语法规范
    注:以下篇章都是用Pycharm写的,具体安装看我主页教程:2024最新:Python与PyCharm下载教程(含汉化!!!)一、什么是Python?标准版:Python是一种高级的、动态类型的编程语言,以其简洁的语法和丰富的库著称。‌Python由荷兰人吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品,它是一......
  • 6个黑客教程网站,小白也能成大牛!(非常详细)零基础入门到精通,收藏这一篇就够了
    黑客攻击是一项很难掌握的技能,在很大的程度上要求人们对计算机和软件架构的各种概念和网络系统有深入的了解。一般而言,黑客主要有两种:黑帽黑客、白帽黑客。黑帽黑客为了个人利益,利用自身的计算机系统知识侵入系统,这种做法是违法的,需要负法律责任;而白帽黑客则是利用相同的......
  • [实时计算flink]数据摄入YAML作业快速入门
    实时计算Flink版基于Flink CDC,通过开发YAML作业的方式有效地实现了将数据从源端同步到目标端的数据摄入工作。本文介绍如何快速构建一个YAML作业将MySQL库中的所有数据同步到StarRocks中。前提条件已创建Flink工作空间,详情请参见开通实时计算Flink版。上下游存储已创建......