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

*题解:CF2229E Deconstruction Tree

题目链接

解析

数数题,考虑 dp。

考虑树形 dp,发现状态设不出来,因为选叶子的过程是在各个子树之间横跳的,设一个只包含一个子树内信息的状态显然无法解决问题。

然后发现状态更设不出来了,返回去找性质。于是发现一个结论:在操作过程中,在加入当前选中叶子 \(x\)\(S\) 后,\(x = S_{\max}\),也就是说 \(x\) 是单调不减的。这也意味着 \(x\) 想要被选,必须要求 \(S\) 中的最大值 \(S_{\max} \le x\)

要想选中 \(x\),还需要 \(x\) 变为叶子,即以 \(x\) 为根,将其儿子删到只留下一个,根据上一条结论,删掉的结点中,其最大编号应当小于 \(x\)。由于有结点 \(n\) 的存在,如果 \(n\) 变为叶子就会把其它结点全部删完。所以如果 \(x\neq n\) 能被选中,那么留下来的那个儿子的子树必定是 \(n\) 所在的子树。直接令 \(n\) 为根,就只用看所有儿子子树内编号最大值了。

\(f_i\) 表示操作过程中以 \(i\) 为最大值的不同 \(S\) 个数,\(g_i\) 表示 \(i\) 的儿子的子树内结点编号最大值。在 \(i\) 加入前,\(S_{\max} < i\),同时由于有 \(g_i\) 的存在,为了删掉 \(g_i\) 及编号更小的点,需要有 \(S_{\max} > g_i\)。据此,可列出状态转移方程:

\[f_i=\sum_{j=g_i + 1} ^ {i - 1} f_j \]

注意 \(n\) 是例外的,因为 \(n\) 为根,其能被选时,即度为 \(1\) 时可以连接着一棵子树,这棵子树必定为 \(n - 1\) 所在子树。故改变 \(g_n\) 定义,求 \(g_n\) 时避开 \(n - 1\) 所在子树。

\(f\) dp 的时候求前缀和,转移时差分即可做到 \(O(n)\) 的时间复杂度。

代码

转移时注意判 \(g_i < i\)

/*
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 2e5 + 5,M = 10 + 5,L = 19,L2 = 17,mod = 998244353;
vector<int> t[N];
int f[N],g[N],pre[N];
int mx;
void dfs(int x,int f){for(int nx : t[x])if(nx != f){dfs(nx,x);g[x] = max({g[x],g[nx],nx});	}if(t[x].size() == 1){mx = max(mx,x);}
}
signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);int T;cin>>T;while(T--){int n;cin>>n;for(int i=1;i<n;i++){int u,v;cin>>u>>v;t[u].push_back(v);t[v].push_back(u);}dfs(n,0);g[n] = 0;for(int nx : t[n]){if(max(g[nx],nx) != n - 1){g[n] = max(g[n],max(g[nx],nx));}}f[mx] = 1;pre[mx] = 1;for(int i=mx + 1;i<=n;i++){if(g[i] < i)f[i] = (pre[i - 1] + mod - pre[g[i]]) % mod;pre[i] = (pre[i - 1] + f[i]) % mod;}cout<<f[n]<<'\n';for(int i=0;i<=n;i++){t[i].clear(); f[i] = pre[i] = g[i] = 0;}mx = 0;}return 0;
}
http://www.rkmt.cn/news/1394853.html

相关文章:

  • 几何级数的本质:从收敛条件到Python实战
  • 跨平台资源下载神器res-downloader:5分钟掌握视频号、抖音无水印下载完整指南
  • Seraphine终极指南:5分钟掌握英雄联盟智能助手,轻松提升游戏胜率
  • 避坑指南:在Ubuntu 20.04上搞定VCS和Verdi安装(含gcc版本依赖和lib库缺失解决)
  • WPA2-PSK WiFi攻防实战:从网卡驱动到handshake破解全流程
  • 基于DTW与XGBoost的能源安全指数高频预测:代理变量遴选与建模实战
  • Tableau Prep Builder数据准备实战:构建可信、可维护的数据流水线
  • Shiro反序列化漏洞原理与Wireshark流量分析实战
  • 2026智能会议室音视频集成厂家推荐及选择要点 - 品牌排行榜
  • 从 GitHub 克隆到验证通过:手把手教你用 libsnark_sample 跑通第一个零知识证明 Demo
  • N46Whisper技术解析:基于Whisper的日语字幕生成架构设计与性能优化
  • 基于RTTTL格式的单片机音乐播放器:从原理到实践
  • DVWA文件上传漏洞原理与四层纵深防御实践
  • STM32实战:用MPU6050的FIFO中断实现5ms精准姿态采集(附完整代码)
  • 在自动化工作流中集成Taotoken API实现智能内容批处理
  • ChatGPT赋能文献综述:从海量PDF到结构化综述框架,72小时内完成导师认可的初稿
  • 毕业论文查重率居高不下,有哪些真正值得入手的的降AIGC平台推荐?
  • Rust宏编程深度实战:声明宏与过程宏的完全指南
  • 从芯片引脚到双绞线:手把手调试STM32的RS485通信(附SP3485电路详解)
  • Kaggle特征工程实战:从业务解码到防泄露提分
  • FPGA实时视频滤波:自定义浮点与DSL实现硬件加速
  • 基于神经OpenIE与动态词嵌入的物联网日志解析框架实践
  • 从监控摄像头到智能灯:手把手教你用闲置路由器+POE模块搭建低成本智能家居供电网
  • 量子优化算法在软件工程中的应用与实现
  • md5_1038参数签名逆向与Python纯算复现指南
  • 全球仅3家机构验证通过的AI Agent跨链意图执行框架:含可信硬件锚点设计、Gas动态预测模型与审计报告摘要
  • 用ADA4530-1静电计放大器DIY一个简易的‘电子听诊器’,手把手教你检测环境微电流
  • 2026海口手表回收平台综合实力排名:6 家平台四大维度正向盘点添价收最优 - 薛定谔的梨花猫
  • PlayAI多语种翻译API接入全流程,从Token鉴权到术语库热加载,手把手带跑通生产环境!
  • 用AI视频分析技术自动提取视频精华:从会议记录到内容创作