请容许我不理解一下为什么这题题解几乎全都是指针实现/kk

其实长链剖分是可以直接用数组来写的。

考虑朴素 DP。设 \(f_{u,i}\) 表示以点 \(u\) 为根的子树中与点 \(u\) 距离为 \(i\) 的点的个数。

则转移方程为:

\[f_{u,i}=\sum\limits_{v\in son_u} f_{v,i-1}
\]

答案为:

\[ans_u=\max\{f_{u,i}\}
\]

转移方程以深度为下标,可以使用长链剖分优化。

在重链剖分时,我们定义一个节点的重儿子为 \(siz\) 最大的儿子,而长链剖分时则是把能到达深度最深的点作为重儿子。

这样,每次我们先对于 \(u\) 的重儿子 DP,那么点 \(u\) 可以直接继承 \(son_u\) 的 DP 值,再暴力合并其它轻儿子。

对于每个点,只会在它所在长链的顶端被暴力合并一次,时间复杂度为 \(O(n)\)。

观察到 \(f_v\) 在继承过来的时候是需要向后错一位的,这导致我们需要用一些特殊方法来存储 DP 值。

这里提供一种数组实现的思路。

对于 DP 数组 \(f\),我们把 \(f_{u,i}\) 映射到下标 \(dfn_u+i\) 的位置上。由于每次我们先遍历 \(son_u\),那么得到 \(dfn_{son_u}=dfn_u+1\)。

也就是说,\(f_{v,0}\) 和 \(f_{u,1}\) 映射的位置相同,恰好向后错了一位。

由于需要保证空间复杂度 \(O(n)\),在每求完一个点的 DP 值后统计该点的答案。

这个写法只是把一个指针数组换成了 \(dfn\) 数组,对空间复杂度似乎没啥影响(?)

#include<bits/stdc++.h>
#define il inline
using namespace std;
il int read()
{
int xr=0,F=1; char cr=getchar();
while(cr<'0'||cr>'9') {if(cr=='-') F=-1;cr=getchar();}
while(cr>='0'&&cr<='9')
xr=(xr<<3)+(xr<<1)+(cr^48),cr=getchar();
return xr*F;
}
const int N=1e6+5;
int n;
struct edge{
int nxt,to;
}e[N<<1];
int head[N],cnt;
void add(int u,int v){
e[++cnt]={head[u],v};head[u]=cnt;
}
int dep[N],son[N],dfn[N],tot;
void dfs1(int now,int fa)
{
for(int i=head[now];i;i=e[i].nxt)
{
int v=e[i].to;if(v==fa) continue;
dfs1(v,now);
if(dep[v]>dep[son[now]]) son[now]=v;
}
dep[now]=dep[son[now]]+1;
}
int f[N],ans[N];
void dfs2(int now,int fa)
{
dfn[now]=++tot;
f[dfn[now]]=1;
if(son[now])
{
dfs2(son[now],now);
if(f[dfn[son[now]]+ans[son[now]]]>1) ans[now]=ans[son[now]]+1;
}
for(int i=head[now];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==son[now]||v==fa) continue;
dfs2(v,now);
for(int j=1;j<=dep[v];j++)
{
f[dfn[now]+j]+=f[dfn[v]+j-1];
if(f[dfn[now]+j]>f[dfn[now]+ans[now]]||
f[dfn[now]+j]==f[dfn[now]+ans[now]]&&j<ans[now]) ans[now]=j;
}
}
}
int main()
{
n=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs1(1,0),dfs2(1,0);
for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
return 0;
}

upd:感觉这么搞局限性还是很大。指针还是该学学的。/kk

关于长链剖分的数组实现 | CF1009F Dominant Indices的更多相关文章

  1. 【CF1009F】Dominant Indices(长链剖分)

    [CF1009F]Dominant Indices(长链剖分) 题面 洛谷 CF 翻译: 给定一棵\(n\)个点,以\(1\)号点为根的有根树. 对于每个点,回答在它子树中, 假设距离它为\(d\)的 ...

  2. BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)

    BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...

  3. 【CF1009F】Dominant Indices(长链剖分优化DP)

    点此看题面 大致题意: 设\(d(x,y)\)表示\(x\)子树内到\(x\)距离为\(y\)的点的个数,对于每个\(x\),求满足\(d(x,y)\)最大的最小的\(y\). 暴力\(DP\) 首先 ...

  4. CF1009F Dominant Indices——长链剖分优化DP

    原题链接 \(EDU\)出一道长链剖分优化\(dp\)裸题? 简化版题意 问你每个点的子树中与它距离为多少的点的数量最多,如果有多解,最小化距离 思路 方法1. 用\(dsu\ on\ tree\)做 ...

  5. (持续更新)虚树,KD-Tree,长链剖分,后缀数组,后缀自动机

    真的就是讲课两天,吸收一个月呢! \(1.\)虚树 \(2.\)KD-Tree \(3.\)长链剖分 \(4.\)后缀数组 后缀数组 \(5.\)后缀自动机 后缀自动机

  6. 【CF1009F】 Dominant Indices (长链剖分+DP)

    题目链接 \(O(n^2)\)的\(DP\)很容易想,\(f[u][i]\)表示在\(u\)的子树中距离\(u\)为\(i\)的点的个数,则\(f[u][i]=\sum f[v][i-1]\) 长链剖 ...

  7. CF1009F Dominant Indices(树上DSU/长链剖分)

    题目大意: 就是给你一棵以1为根的树,询问每一个节点的子树内节点数最多的深度(相对于这个子树根而言)若有多解,输出最小的. 解题思路: 这道题用树链剖分,两种思路: 1.树上DSU 首先想一下最暴力的 ...

  8. CF1009F Dominant Indices 长链剖分

    题目传送门 https://codeforces.com/contest/1009/problem/F 题解 长链剖分的板子吧. 令 \(dp[x][i]\) 表示 \(x\) 的子树中的深度为 \( ...

  9. LOJ3053 十二省联考2019 希望 容斥、树形DP、长链剖分

    传送门 官方题解其实讲的挺清楚了,就是锅有点多-- 一些有启发性的部分分 L=N 一个经典(反正我是不会)的容斥:最后的答案=对于每个点能够以它作为集合点的方案数-对于每条边能够以其两个端点作为集合点 ...

  10. 2018牛客网暑假ACM多校训练赛(第七场)I Tree Subset Diameter 动态规划 长链剖分 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round7-I.html 题目传送门 -  https://www.n ...

随机推荐

  1. 【Shell】数组

    数组 bash 只支持一维数组. 数组下标从 0 开始,下标可以是整数或算术表达式,其值应大于或等于 0. 创建数组 # 创建数组的不同方式 nums=([2]=2 [0]=0 [1]=1) colo ...

  2. 【Python】爬虫-Xpath

    Xpath 文章参考:https://www.cnblogs.com/mxjhaima/p/13775844.html#案例 安装 pip install lxml 引用 from lxml impo ...

  3. Day07_Java_作业

    A:简答题 1. 构造方法的作用是什么?构造方法的特点是什么?构造方法的注意事项? 构造方法中可不可以写return语句呢? 2. 一个类的缺省构造方法可以有参数吗? 3. 静态代码块和构造代码块的特 ...

  4. 初始elasticSearch

    elasticSearch 大致印象 为什么用? mysql更擅长于crud等操作,当一张表达到百万级别时,检索速度过慢 es检索速度快 基本概念 Index索引(两层意思) 动词:类似mysql的i ...

  5. 学习LVM:archive 和 backup目录

    推荐文档:Logical Volume Manager Administration 在掌握了基本的commands操作后,你是否对操作背后的一些东西产生好奇呢? 程序的configure一般会提供这 ...

  6. Yunfly 一款高效、性能优异的 node.js web 框架

    介绍 Yunfly 一款高性能 Node.js WEB 框架, 使用 Typescript 构建我们的应用. 使用 Koa2 做为 HTTP 底层框架, 使用 routing-controllers ...

  7. 关于 LLM 和图数据库、知识图谱的那些事

    本文整理自 NebulaGraph 布道师 wey 在「夜谈 LLM」主题分享上的演讲,主要包括以下内容: 背景 LLM RAG Graph 知识抽取 Text2Cypher Graph RAG 未来 ...

  8. 【pytorch】目标检测:一文搞懂如何利用kaggle训练yolov5模型

    笔者的运行环境:python3.8+pytorch2.0.1+pycharm+kaggle.yolov5对python和pytorch版本是有要求的,python>=3.8,pytorch> ...

  9. API技术的使用场景

    ​ 互联网的发展和普及,API技术也变得越来越重要.API是应用程序接口,它是一种连接不同应用程序或系统之间数据交换和通信的方式.API技术不仅提高了不同应用程序之间的互操作性,还加速了应用程序的开发 ...

  10. COF框架集成mongodb驱动

    今天打算在我的COF框架中集成mongodb驱动,这实在是简单的工作,因为基本上只是对pymongo的封装 数据库的集成大同小异,要考虑的点无非是以下几点: 1.命名 2.连接创建 3.连接池管理 4 ...