【知识总结】dfs序 树链剖分

简介: 【知识总结】dfs序 树链剖分

视频:传送门1传送门2

dfs序和树链剖分两者都借助hash的思想是将树形转化成线性的算法,前者主要处理子树问题,后者主要处理链的问题。

1.dfs序

定义: 顾名思义是按照dfs的顺序标号。

重要性质:每棵子树内的标号都是连续的,某些链的标号也是连续的。

代码:

int timetmp;///时间戳,计数器
int in[maxn];///表示dfs进某节点的时间
int out[maxn];///表示dfs出某节点的时间
///差值就是子树的节点个数
vector<int>e[maxn];///存图
void dfs(int u,int fa){
    in[u]=++timetmp;
    for(int i=0;i<e[u].size();i++){
        int j=e[u][i];
        if(j==fa) continue;
        dfs(j,u);
    }
    out[u]=timetmp;
}

例题1:(卿学姐给的例题 没找到来源)


题意:两种操作 1.将子树的所有节点的权值都+v 2.查询某子树的权值的max


思路:按照dfs序给所有节点标号,这样就将树上问题转化成了区间问题,由重要性质我们可以把操作一转化为区间加法,操作二转化为区间最值,用线段树维护就可以了。


例题2:(POJ3321)


题意:两种操作 1.修改某个节点的权值,如果原来是1,修改为0,如果原来是0,修改为1 ; 2.查询某子树的权值和


思路:转化为dfs序后,就转化成了单点修改、区间查询的问题,用树状数组或线段树维护即可。


2.树链剖分(重链剖分 logn)

基本概念:(sz[x]表示x的子树个数)


重儿子:某节点的所有子节点里sz[x]最大的子节点(如果有多个就随便取一个)


轻儿子:一个节点除了重儿子以外的儿子


重链:从一个轻儿子(根节点也是轻儿子)开始,每次往重儿子走连出的链


轻链:除了重链全是轻链


模拟过程:


第一遍dfs:记录节点的父亲、重儿子、深度、大小


第二遍dfs:记录节点权值的dfs序和时间戳,当前节点所在重链的头是谁

int son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
///son[]重儿子编号,id[]新编号,fa[]父亲节点,cnt dfs_clock/dfs序,dep[]深度,siz[]子树大小,top[]当前链顶端节点
int res=0;
///查询答案
inline void dfs1(int x,int f,int deep){//x当前节点,f父亲,deep深度
    dep[x]=deep;//标记每个点的深度
    fa[x]=f;//标记每个点的父亲
    siz[x]=1;//标记每个非叶子节点的子树大小
    int maxson=-1;//记录重儿子的儿子数
    for(int i=h[x];i;i=ne[i]){
        int y=e[i];
        if(y==f)continue;//若为父亲则continue
        dfs1(y,x,deep+1);//dfs其儿子
        siz[x]+=siz[y];//把它的儿子数加到它身上
        if(siz[y]>maxson)son[x]=y,maxson=siz[y];//标记每个非叶子节点的重儿子编号
    }
}
inline void dfs2(int x,int topf){//x当前节点,topf当前链的最顶端的节点
    id[x]=++cnt;//标记每个点的新编号
    wt[cnt]=w[x];//把每个点的初始值赋到新编号上来
    top[x]=topf;//这个点所在链的顶端
    if(!son[x])return;//如果没有儿子则返回
    dfs2(son[x],topf);//按先处理重儿子,再处理轻儿子的顺序递归处理
    for(int i=h[x];i;i=ne[i]){
        int y=e[i];
        if(y==fa[x]||y==son[x])continue;
        dfs2(y,y);//对于每一个轻儿子都有一条从它自己开始的链
    }
}

重要性质:


重链上的编号都是连续的。


任何一条路径都是由重链的一部分和叶子节点组成的。


除根节点外的任意一个节点的父节点一定在一条重链上。


然后一般就再用树状数组或线段树维护信息。


例题:(洛谷P3384)


思路:


树剖之后操作3和操作4都利用区间修改和区间查询可以解决。

inline int qSon(int x){///操作4
    res=0;
    query(1,1,n,id[x],id[x]+siz[x]-1);//子树区间右端点为id[x]+siz[x]-1
    return res;
}
inline void updSon(int x,int k){//操作3
    update(1,1,n,id[x],id[x]+siz[x]-1,k);
}

对于操作1和操作2,如果两个节点在一条重链上,问题就转化成了区间修改和区间查询;如果不在一条重链上,可以维护两个指针指向两个节点,不停地让dep[top[i]]大的节点的指针沿着所在重量往上跳,同时在线段树上进行操作,直到两指针到同一节点或同一重链。

int qRange(int x,int y){//操作2  表示求树从 x到 y 结点最短路径上所有节点的值之和
    int ans=0;
    while(top[x]!=top[y]){//当两个点不在同一条链上
        if(dep[top[x]]<dep[top[y]])swap(x,y);//把x点改为所在链顶端的深度更深的那个点
        res=0;
        query(1,1,n,id[top[x]],id[x]);//ans加上x点到x所在链顶端 这一段区间的点权和
        ans+=res;
        ans%=mod;//按题意取模
        x=fa[top[x]];//把x跳到x所在链顶端的那个点的上面一个点
    }
    //直到两个点处于一条链上
    if(dep[x]>dep[y])swap(x,y);//把x点变为深度更深的那个点
    res=0;
    query(1,1,n,id[x],id[y]);//这时再加上此时两个点的区间和即可
    ans+=res;
    return ans%mod;
}

待补

【牛客】2020牛客暑期多校训练营(第七场)C- A National Pandemic

目录
相关文章
|
3天前
|
人工智能 弹性计算 运维
开启运维新纪元!阿里云OS Copilot深度评测 & 体验分享
OS Copilot是Alibaba Cloud为Linux推出的一款基于大模型的智能助手,它能理解自然语言、辅助命令执行和系统运维。目前仅支持Alibaba Cloud Linux 3的x86_64架构。安装过程涉及线上和本地体验,包括申请试用、配置环境变量、安装组件等步骤。OS Copilot提供命令行和多轮交互模式,能进行代码生成和摘要,辅助开发和运维工作。产品体验评测中,OS Copilot因其自然语言理解和高效辅助得到高度评价,尤其对运维人员来说,能大幅提升工作效率。然而,目前仅限于特定操作系统,是其局限性。未来有望扩展更多功能和支持更多平台。
86407 13
|
6天前
|
人工智能 弹性计算 API
创意“孵化机”——基于通义万相加速绘画创作流程
阿里云在2023年推出了AI绘画平台**通义万相**,该平台能够根据文本描述生成图像,应用于艺术创作。近期,阿里云优化了通义万相的接入方式,提供API文档和一键部署服务,使得非技术人员也能轻松集成到Web应用中。为促进用户尝试,阿里云还推出了解决方案评测活动,参与者有机会获得奖品。通义万相通过ECS、OSS、VPC和DashScope等云服务支持,简化了技术架构,加速了绘画创作流程。此外,阿里云提供了优惠购买方案,新人享有特别折扣。该服务不仅适用于艺术家,还可应用于多个领域,提高内容生成效率。
70721 19
|
9天前
|
人工智能 自然语言处理 算法
阿里云PAI大模型评测最佳实践
在大模型时代,模型评测是衡量性能、精选和优化模型的关键环节,对加快AI创新和实践至关重要。PAI大模型评测平台支持多样化的评测场景,如不同基础模型、微调版本和量化版本的对比分析。本文为您介绍针对于不同用户群体及对应数据集类型,如何实现更全面准确且具有针对性的模型评测,从而在AI领域可以更好地取得成就。
|
14天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!
|
14天前
|
机器学习/深度学习 算法 开发工具
通义千问2(Qwen2)大语言模型在PAI-QuickStart的微调、评测与部署实践
阿里云的人工智能平台PAI,作为一站式的机器学习和深度学习平台,对Qwen2模型系列提供了全面的技术支持。无论是开发者还是企业客户,都可以通过PAI-QuickStart轻松实现Qwen2系列模型的微调、评测和快速部署。
|
16天前
|
人工智能 机器人 API
用AppFlow玩转通义百炼大模型应用
阿里云百炼平台提供一站式大模型开发服务,支持创建和定制应用,预置丰富插件和API。用户可以通过平台快速构建大模型应用,并利用AppFlow将其接入钉钉群聊,以AI卡片形式展示。
72978 5
|
14天前
|
存储 网络协议 安全
阿里云hpc8ae实例商业化发布详解
近日,全球领先的云计算厂商阿里云宣布最新HPC优化实例hpc8ae的正式商业化,该实例依托阿里云自研的「飞天+CIPU」架构体系,搭载第四代AMD EPYC处理器,专为高性能计算应用优化,特别适用于计算流体、有限元分析、多物理场模拟等仿真类应用,CAE场景下的性价比最少提升50%。
|
15天前
|
SQL 搜索推荐 OLAP
Flink 流批一体场景应用及落地情况
本文由阿里云 Flink 团队苏轩楠老师撰写,旨在介绍 Flink 流批一体在几个常见场景下的应用。
67528 3
Flink 流批一体场景应用及落地情况
|
15天前
|
Kubernetes 测试技术 应用服务中间件
基于 Nginx Ingress + 云效 AppStack 实现灰度发布
本文将演示结合云效 AppStack,来看下如何在阿里云 ACK 集群上进行应用的 Ingress 灰度发布。
64565 18
|
13天前
|
域名解析 弹性计算 运维
基于云效流水线高效构建企业门户网站体验评测
阿里云云效流水线作为一款企业级持续集成和持续交付工具,在助力高效构建企业门户网站方面表现出色。
37721 8
基于云效流水线高效构建企业门户网站体验评测