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

换根dp的一个trick

最近遇到了很多次这个trick,所以写个博客记录一下。
P2018 消息传递
but \(n\le2e5\)
先考虑根固定的情况,设 \(f_x\) 表示以 \(x\) 为根的子树全部传达需要的时间,一个很显然的思路是先去 \(x\) 的子节点中 \(f\) 值最大的节点,这样能尽可能让每一刻传递信息的节点尽量多。时间复杂度是 \(O(NlogN)\),但是要对每一个点做一次,复杂度是我们不能接受的。
考虑换根dp,我们想要转移答案,就需要先处理出当前节点除去某个子节点后的 \(f\) 值,在删除某一个节点时,在它之前被选的节点不会受到影响,而在它之后被选的节点会整体提前一个单位时间,所以我们记录一个前缀max和后缀max,那删除某一个子节点y后的 \(f\) 值,就是前缀max和后缀max+1中的较大值,到这里换根dp的实现就很明显了。

vector<int> e[N],t[N],pre[N],suf[N];
void dfs(int x,int fa){for(int i=0;i<e[x].size();i++){int y=e[x][i];if(y==fa)continue;dfs(y,x);t[x].push_back(f[y]);}sort(t[x].begin(),t[x].end());int ans=0;pre[x].resize(t[x].size());suf[x].resize(t[x].size());for(int i=0;i<t[x].size();i++){if(i==0)pre[x][i]=t[x][i]+t[x].size()-i;else pre[x][i]=max(t[x][i]+(int)t[x].size()-i,pre[x][i-1]);ans=max(ans,t[x][i]+((int)t[x].size()-i));}f[x]=ans;for(int i=t[x].size()-1;i>=0;i--){if(i==t[x].size()-1)suf[x][i]=t[x][i]+t[x].size()-i;else suf[x][i]=max(suf[x][i+1],t[x][i]+(int)t[x].size()-i);}
}
void exc(int x,int fa){int ans=0;sort(t[x].begin(),t[x].end());pre[x].resize(t[x].size());suf[x].resize(t[x].size());for(int i=0;i<t[x].size();i++){if(i==0)pre[x][i]=t[x][i]+t[x].size()-i;else pre[x][i]=max(t[x][i]+(int)t[x].size()-i,pre[x][i-1]);ans=max(ans,t[x][i]+((int)t[x].size()-i));}g[x]=ans;for(int i=t[x].size()-1;i>=0;i--){if(i==t[x].size()-1)suf[x][i]=t[x][i]+t[x].size()-i;else suf[x][i]=max(suf[x][i+1],t[x][i]+(int)t[x].size()-i);}for(int i=0;i<e[x].size();i++){int y=e[x][i];if(y==fa)continue;int p=lower_bound(t[x].begin(),t[x].end(),f[y])-t[x].begin();int num=0;if(p>0)num=max(num,pre[x][p-1]-1);if(p<t[x].size()-1)num=max(num,suf[x][p+1]);g[y]=max(f[y],num+1);t[y].push_back(num);exc(y,x);}
}

在换根dp时,这种记录前缀后缀来消除某个节点的trick是很常用的

http://www.hskmm.com/?act=detail&tid=29149

相关文章:

  • 搭建SSH服务于RK3399平台上的Ubuntu 18.04,实现远程连接
  • 深入探讨MySQL的二进制日志(binlog)选项
  • sparkml 多列共享labelEncoder - 详解
  • 一键解决MetaHuman播放动画时头部穿模问题
  • 忽然很好奇为什么素未谋面的大家都知道我是学姐?
  • UE网络编程完全指南:UDP TCP WebSocket实现详解
  • 配置Nginx服务器在Ubuntu平台上
  • 缓存一致性验证秘笈
  • 从十五岁的今天写给十六岁的明天
  • kali U盘启动持久化
  • 深入解析:Telerik UI for ASP.NET MVC 2025 Q3
  • Java依记 DAY02 - I
  • 元推理:汉字的发音,同音也是某种同构?
  • 题解:qoj7759 Permutation Counting 2
  • WAV 转 flac 格式
  • EtherCAT芯片没有倍福授权的风险
  • 为何是「对话式」智能体?因为人类本能丨对话式智能体专场,Convo AIRTE2025
  • 2014-2024高考真题考点分布详细分析(另附完整高考真题下载) - 详解
  • P4147 玉蟾宫(最大子矩形)
  • 2025 年 10 月西安房屋鉴定公司最新推荐排行榜:覆盖房屋安全评估、结构检测、承载力鉴定、危房鉴定领域,助您选专业机构
  • 完整教程:HAProxy 完整指南:简介、负载均衡原理与安装配置
  • K
  • 阿里发布「夸克 AI 眼镜」:融合阿里购物、地图、支付生态;苹果拟收购计算机视觉初创 Prompt AI丨日报
  • 在AI技术唾手可得的时代,挖掘新需求成为制胜关键——某知名AI聊天框架需求探索
  • 数论学习之路
  • 生成式AI实现多模态信息检索技术突破
  • 在运维工作中,如何过滤某个目录在那边什么路径下面?
  • 完整教程:安卓中,kotlin如何写app界面?
  • 移动固态硬盘插入电脑后提示“应该格式化”或“文件系统损坏”如何修复?
  • PHP 15 个高效开发的小技巧