1 条题解
-
0
「ZJOI2020」传统艺能 题解
题目分析
给定一棵广义线段树,执行 次操作,每次操作等概率随机选择一个区间 进行懒标记操作。求 次操作后,有标记的节点的期望数量。
核心算法:概率期望 + 矩阵快速幂
关键思路
对于每个节点,考虑其在 次操作后被标记的概率,然后利用期望的线性性求和。
节点状态分类
对于任意非根节点 ,定义三种状态:
- 状态 0:节点 和其父亲都没有标记
- 状态 1:父亲有标记,但 没有
- 状态 2:节点 有标记
概率转移矩阵
对于每个节点,构建 的转移矩阵 ,其中 表示从状态 转移到状态 的概率。
关键概率计算
-
:操作区间完全包含节点 的概率
$$Include(x) = \frac{l_x \times (n - r_x + 1)}{\frac{n(n+1)}{2}} $$ -
:操作区间与节点 相交的概率
$$Intersect(x) = 1 - \frac{\binom{l_x-1}{2} + \binom{n-r_x}{2}}{\binom{n}{2}} $$ -
:操作区间访问到节点 但不访问其父亲的概率
-
:操作区间访问到父亲但不访问 的概率
矩阵构建
转移矩阵为:
$$M = \begin{bmatrix} p_{00} & p_{01} & p_{02} \\ 0 & p_{11} & p_{12} \\ 0 & 0 & 1 \end{bmatrix} $$其中:
- $p_{00} = (Include(fa_x) + NoIntersect(fa_x)) \times qV$
- $p_{11} = (NoIntersect(fa_x) + VisitCousin(x)) \times qV$
算法流程
- 建树:根据先序遍历的划分位置构建广义线段树
- DFS 遍历:对每个节点计算转移矩阵
- 矩阵快速幂:计算 得到 次操作后的状态概率
- 累加期望:每个节点的状态 2 的概率贡献到答案
复杂度分析
- 时间复杂度:,每个节点需要 的矩阵快速幂
- 空间复杂度:,存储线段树结构
算法标签
主要分类
- 动态规划 ⭐⭐⭐⭐
- 概率期望 ⭐⭐⭐⭐⭐
- 矩阵快速幂 ⭐⭐⭐⭐
技术子标签
- 状态机设计 ⭐⭐⭐⭐
- 组合计数 ⭐⭐⭐⭐
- 线段树性质分析 ⭐⭐⭐⭐
数学工具
- 线性代数 ⭐⭐⭐
- 模运算 ⭐⭐⭐
代码核心解析
// 构建转移矩阵 mat.a[0][0] = (Include(t[x].fa) + NoIntersect(t[x].fa)) % P * qV % P; mat.a[0][1] = VisitCousin(x) * qV % P; mat.a[0][2] = Visit(x) * qV % P; mat.a[1][1] = (NoIntersect(t[x].fa) + VisitCousin(x)) % P * qV % P; mat.a[1][2] = (Include(t[x].fa) + Visit(x)) * qV % P; mat.a[2][2] = 1; // 矩阵快速幂计算k次操作后的状态 ans += qpow(mat, k).a[0][2];创新点总结
- 状态机建模:将复杂的标记传播过程抽象为三状态马尔可夫链
- 概率计算:利用组合数学精确计算各种区间操作的概率
- 矩阵优化:使用矩阵快速幂处理大规模操作次数
- 期望线性性:将整体期望分解为每个节点的期望之和
该解法通过巧妙的概率建模和矩阵优化,成功解决了大规模操作下的期望计算问题。
- 1
信息
- ID
- 4105
- 时间
- 3500ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者