P14254 分割(树上计数问题) 题解

news/2025/10/20 21:01:30/文章来源:https://www.cnblogs.com/director-ni/p/19153649

P14254 树上组合计数(分割问题)题解

原题链接

一、题目分析

这部分是解题的核心,通过分析条件得出简化问题的关键结论。

  1. 计数问题先尝试找一下性质:

    • 注意到节点的选择只能越来越深

      \[d_i>=d_1 \]

    • 最关键性质:

      \[max L_i =d_i ,min R_i ==high_i \]

      \[L_i =d_i<=d_1,\therefore d_i=d_1 \]

  2. 所以所选点的深度相等

    • 定义“高度”hig[x]:结点x到其所在子树中叶子结点的最大深度(即子树内的最大深度)。
    • 核心约束:设选中结点均在深度为x的层,需满足“所有选中结点的高度最小值等于第一个结点的高度”(min Rᵢ = R₁,其中Rᵢ为结点i的高度)。

三、计数思路

基于上述性质,计数过程按“逐层处理”展开,每层内再按高度分组计算贡献。

1. 预处理步骤

  • 步骤1:计算深度与高度:通过DFS遍历树,记录每个结点的深度dep[x]和高度hig[x]。
  • 步骤2:分层与分组
    • 按深度将结点分组,得到flr[i](存储深度为i的所有结点的高度)。
    • 对每层的flr[i]按高度排序,并进一步按相同高度分组,记录每组的结点数量(nt)和该组在层中的位置(bef,用于计算后续结点数)。

2. 每层贡献计算

对每个深度为i的层,若该层结点数<k+1,则直接跳过(无法满足选k个结点的基本条件);否则按以下公式计算该层的贡献:

(1)核心公式

对于高度相同的一组结点(数量为t,后续结点数为s,s=该层总结点数 - 该组位置bef):

  • 若满足t≥2(需至少2个结点,1个作为序列第一个元素,1个用于限制高度最小值)且t+s≥k+1(总可选结点数足够),则该组贡献为:

[ \text{贡献} = t \times \left( A(t+s-1, k-1) - A(s, k-1) \right) ]

  • 特殊情况:当s=k-1时,A(s, k-1)需强制设为0(此时后续结点数恰好为k-1,无法满足高度约束)。

(2)排列数定义

  • 排列数A(a, b)表示从a个元素中选b个元素进行有序排列的方案数。
  • 计算公式:若b<0或a<b,则A(a,b)=0;否则A(a,b)=fac[a] × inf[a-b] mod 998244353。
  • 其中fac为阶乘数组,inf为逆阶乘数组(通过费马小定理预处理,inf[n] = fac[n]^(M-2) mod M,M=998244353)。

四、代码实现

1.完整代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5, M = 998244353;
struct Edge
{int to, next;
} e[N];
int head[N], idx = 0;
void addedge(int u, int v)
{e[idx].to = v;e[idx].next = head[u];head[u] = idx++;
}
int phi(int a, int b)
{int res = 1;while (b){if (b & (int)1)res = (res * a) % M;b >>= (int)1;a = (a * a) % M;}return res;
}
int n, k;
int dep[N], hig[N];
vector<int> flr[N];
int fac[N], inf[N];
void init()
{fac[1] = fac[0] = 1;for (int i = 1; i <= n; ++i)fac[i] = (fac[i - 1] * i) % M;inf[n] = phi(fac[n], M - 2);for (int i = n - 1; i >= 0; --i)inf[i] = (inf[i + 1] * (i + 1)) % M;
}
int maxdep = 0;
void dfs(int x)
{hig[x] = dep[x];maxdep = max(maxdep, dep[x]);for (int i = head[x]; ~i; i = e[i].next){int v = e[i].to;dep[v] = dep[x] + 1;dfs(v);hig[x] = max(hig[x], hig[v]);}
}
int A(int a, int b)
{if (b < 0 || a < b)return 0;return (fac[a] * inf[a - b]) % M;
}
struct Seg
{int nt = 0, bef = 0;
};
signed main()
{memset(head, -1, sizeof head);cin >> n >> k;for (int i = 2; i <= n; ++i){int t;cin >> t;addedge(t, i);}dep[1] = 1;dfs(1);init();for (int i = 1; i <= n; ++i)flr[dep[i]].push_back(hig[i]);int ans = 0;for (int i = 1; i <= maxdep; ++i){if (flr[i].size() < k + 1)continue;sort(flr[i].begin(), flr[i].end());vector<Seg> g;int cnt = 1;for (int j = 0; j < flr[i].size(); ++j){if (j < flr[i].size() && flr[i][j] == flr[i][j + 1])++cnt;elseg.push_back({cnt, j + 1}), cnt = 1;}for (Seg j : g){int t = j.nt, s = flr[i].size() - j.bef;if (t >= 2 && t + s >= k + 1){int t1 = A(t + s - 1, k - 1), t2 = A(s, k - 1);if (s == k - 1)t2 = 0;int tp = ((t1 - t2) % M + M) % M;ans = (ans + (t * tp) % M) % M;}}}cout << ans << endl;return 0;
}

2. 易错点提示

​ 排列数函数记得特判

3. 代码说明

  • 树的存储:使用邻接表(Edge结构体+head数组),适配1e6级别的结点规模。
  • 预处理优化:阶乘与逆阶乘通过费马小定理预处理,确保排列数计算O(1)。
  • 边界处理
    • 排列数计算时判断a<b或b<0的情况,直接返回0。
    • 减法取模时加上M再取模,避免出现负数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/941598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完整教程:开源 C++ QT QML 开发(一)基本介绍

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

102302104刘璇综合实践作业任务一:智能购物平台用户需求调研分析报告——基于195份问卷的用户痛点挖掘

摘要: 本报告基于《智能购物平台调查问卷数据及其可视化》收集的195份有效数据,通过科学的可视化分析方法,围绕用户基础特征、烹饪行为习惯、智能功能需求等维度展开深入研究。在两个星期的调研过程中,我从问卷设计…

软件工程第二次团队作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/202501SoftwareEngineering/这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/202501SoftwareEngineering/homework/13559这个作业的目标 使用现代 A…

Hands on Deep Learning Chapter 3 线性神经网络

3 线性神经网络 3.1 线性回归 回归(regression)、预测(prediction)、分类(classification) 3.1.1 线性回归的基本元素 线性模型:对输入特征进行一个仿射变换(affine transformation,加权和对特征进行线性变换…

超越技术范畴:低代码如何重塑企业数字文化

当我们谈论低代码时,目光往往聚焦于其提升开发效率的技术特性。然而,它的深层影响力远不止于此。低代码更像是一颗投入企业静湖的石子,其激起的涟漪,正层层扩散,深刻地重塑着组织的协作模式、创新节奏乃至内在的数…

好用的网址

填验证码(? 题解格式化。 画图。 代码格式化。 纯文字图片生成器。

【C++实战(71)】解锁C++音视频编写:FFmpeg从入门到实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

20251020

正睿NOIP 二十连测 A 有 \(m(m \le 95)\) 种药剂,每种药剂有 \(n_i(\sum n_i \le 10^{15})\) 瓶,等级为 \(p_i\)(\(2 \le p_i \le 499\))。要将这些药剂分成两个不相交的集合 \(X, Y\),\(X\) 的价值为其组内所有药…

低代码赋能业务创新:打破数字鸿沟,释放业务潜能

在数字化转型的浪潮中,一个突出的矛盾日益显现:业务部门汹涌的创新需求,与IT部门有限的开发资源之间,形成了一道难以逾越的“数字鸿沟”。当市场部门需要一个临时的活动报名系统,当HR部门渴望一个高效的内部推荐工…

【大模型】大模型训练的几个不同阶段

总结:各方法的典型关联(以大语言模型为例)Pre-Training:先让模型学“通识知识”(如语言、世界知识)。 Supervised Fine-Tuning (SFT):用标注数据让模型学“任务基本模式”(如指令遵循)。 Reward Modeling:训…

详细介绍:1、手把手教你入门设计半桥LLC开关电源设计,LLC谐振腔器件计算

详细介绍:1、手把手教你入门设计半桥LLC开关电源设计,LLC谐振腔器件计算pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family…

十六天

今日重点学习关系型数据库基础,核心掌握三个模块:一是数据表的结构化设计,明确字段类型(如INT、VARCHAR)需与数据属性匹配,避免后续数据存储异常;二是主键的作用,通过实操验证其“唯一标识记录”的必要性——未…

10/20/2025杂题 关于在线性时间内求解低次多项式的幂

例 设 \(g = ax^2 + bx + c\),求: \[ f = g^n\]其中 \(0 \leq n \leq 3 \times 10^5\)。结果对 \(10^9 + 7\) 取模。 首先可以直接用 MTT 在 \(O(n \log n)\) 的时间复杂度内求解。然而此做法常数太大,在需要多次求…

歌手与模特儿

https://www.luogu.com.cn/problem/AT_nikkei2019_2_final_h 第一次见到能 manacher 但不能二分+哈希的题! 直接上 manacher,当尝试将区间拓展为 \([l,r]\) 时,考察 \(nxt_l\) 和 \(lst_r\) 的位置关系,可以 check…

20251019

正睿 NOIP 十连测 B 有 \(n\) 个数 \(a_1 \sim a_n\)。初始有一个 \(x = 1\),每次需要将 \(x\) 变为某个 \(i\),花费代价为 \(\min(|i - x|, n - |i - x|)\),且 \(a_x \le a_i\)。问访问所有 \(i\) 需花费的最小代价…

计算机毕业设计 基于EChants的海洋气象数据可视化平台设计与建立 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】

计算机毕业设计 基于EChants的海洋气象数据可视化平台设计与建立 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】pre { white-space: pre !important; word-wrap: normal !important; overflo…

SpringBoot整合Redis教程

一、Redis 简介 Redis(Remote Dictionary Server)是一个开源的高性能键值对存储数据库,基于内存运行并支持持久化,常用于缓存、会话存储、消息队列等场景。其核心特点包括:速度快:基于内存操作,单线程模型避免上…

https://www.luogu.com.cn/problem/CF1635E

考虑一个事情,两辆车方向一定相反,弱化限制后,建二元关系图,发现一定是一张二分图。 钦定左部点为向左,其他点为向右,然后发现位置满足一个二元大小关系限制,建 DAG 跑拓扑序即可。

ZR 2025 NOIP 二十连测 Day 5

85 + 32 + 5 + 5 = 127, Rank 67/128.呜呜我错了……我再也不开太大的 vector 了呜呜……/dk /dk /dk25noip二十连测day5 链接:link 题解:题目内 时间:4h (2025.10.20 14:00~18:00) 题目数:4 难度:A B C D\(\colo…

关于单片机内部ADC采样率,采样精度的理解与计算整理 - 实践

关于单片机内部ADC采样率,采样精度的理解与计算整理 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…