1 条题解
-
0
题目理解
我们有一个动态图,初始时没有边。支持两种操作:
-
类型 1:在 和 之间
- 如果不连通:添加一条白色边
- 如果连通:将 到 最短路上的所有白色边染成黑色
-
类型 2:查询如果执行类型 1 操作,会有多少条白边被染黑
关键点:
- 只有白色边会被染黑
- 查询是"如果执行"的,不会实际执行类型 1 操作
- 需要维护连通性和路径信息
算法思路
1. 问题分析
对于类型 2 查询 :
- 如果 和 不连通:输出 -1
- 如果连通:输出 到 路径上的白色边数量
对于类型 1 操作 :
- 如果不连通:添加白边(连接两个连通块)
- 如果连通:将路径上的白边染黑(实际上是将这些边的颜色标记为黑色)
2. 数据结构选择
我们需要支持:
- 动态连接(加边)
- 查询路径信息(白色边数量)
- 路径更新(将白边染黑)
这提示我们使用 Link-Cut Tree (LCT) 或 Euler Tour Tree。
由于操作涉及路径查询和路径更新,LCT 是更合适的选择。
3. LCT 节点设计
每个 LCT 节点维护:
- 该节点代表的边的颜色(如果是边节点)
- 子树中白色边的数量
- 懒标记,表示将子树中的白边染黑
对于边 ,我们在 LCT 中创建一个新节点 表示这条边,然后连接 和 。
4. 操作实现
查询操作 (类型 2):
make_root(A),access(B)- 检查 和 是否连通
- 如果连通,查询路径上的白色边数量
修改操作 (类型 1):
- 检查 和 是否连通
- 如果不连通:添加白边
- 如果连通:将路径上的白边染黑
优化和注意事项
- 边节点管理:我们需要为每条边分配一个节点,可以使用从 开始的编号
- 懒标记传播:正确实现懒标记的传播是关键
- 内存管理:使用数组而不是动态分配可以提高性能
总结
这道题的关键在于:
- 理解操作语义:类型 2 是"如果执行"的查询
- 选择合适的动态树结构:LCT 支持路径查询和更新
- 维护边信息:通过创建边节点来维护边的颜色
- 懒标记优化:使用懒标记进行高效的路径更新
通过 LCT 的路径操作,我们可以在 时间内完成所有操作,满足大数据范围的要求。
-
- 1
信息
- ID
- 5222
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者