CF1009F Dominant Indices
主要思想:长链剖分优化DP
给定一棵以 为根, 个节点的树。设 为 子树中到 距离为 的节点数。
对于每个点,求一个最小的 ,使得 最大。
数据范围
看到这题首先想到DP,对于一个点,需要合并的是它的所有子树同层的点个数,然而直接这样做会T飞 or M飞,考虑此题为子树信息合并,可以想到长链剖分优化DP,每次将一个点的子树的长链信息合并到当前点的长链上,每条链最多合并一次,复杂度神奇地降成 。
优雅代码如下:
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
int f=1,j=0;
char w=getchar();
while(w>'9'||w<'0')w=getchar();
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
const int N=1000001;
int n,dep[N],d_dep[N];
int son[N],to[N],siz[N];
int ans[N],ans_siz[N];
vector<int>line[N];
void dfs1(int u,int fa){
dep[u]=dep[fa]+1;
d_dep[u]=dep[u];
siz[u]=1;
for(int x:line[u]){
if(x==fa)continue;
dfs1(x,u);
if(d_dep[x]>d_dep[u]){
d_dep[u]=d_dep[x];
son[u]=x;
}
}
to[u]=son[u];
return ;
}
void merge(int x,int y){
int u=x,len=1;x=to[x];
while(y!=0){
siz[x]+=siz[y];
if(siz[x]>ans_siz[u]||(siz[x]==ans_siz[u]&&len<ans[u]))ans[u]=len,ans_siz[u]=siz[x];
x=to[x];y=to[y];
len++;
}
return ;
}
void dfs2(int u,int fa){
if(son[u])dfs2(son[u],u);
if(son[u]==0||ans[son[u]]==0)ans[u]=0,ans_siz[u]=1;
else ans[u]=ans[son[u]]+1,ans_siz[u]=ans_siz[son[u]];
for(int x:line[u]){
if(x==fa||x==son[u])continue;
dfs2(x,u);
merge(u,x);
}
return ;
}
signed main(){
n=rd();
for(int i=1;i<n;i++){
int x=rd(),y=rd();
line[x].push_back(y);
line[y].push_back(x);
}
dfs1(1,0);
dfs2(1,0);
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】