1 条题解
-
0
题解
思路
1. 判定条件
设当前可用图中点 的出度为 。
如果所有 ,那么从任意点不断沿唯一出边前进。由于点数有限,路径最终必然进入一个有向环,因此可以无限穿梭;同时唯一出边也满足连续穿梭条件。
反过来,题意直接要求每个点恰有一条可用出边。因此一次操作后的答案等价于判断
不需要显式维护连通性或有向环。
做法
2. 子任务 1:全量扫描
保存每条边的可用状态。单边操作修改一条边,整点操作枚举所有终点为该点的边。每次操作后重新统计所有点的出度并检查是否全为 。
复杂度为 ,空间复杂度为 ,适用于 。
3. 子任务 2:维护坏点个数
继续显式保存每条边的状态,同时维护每个点的当前出度 ,以及
修改一条边时,只需在修改前后分别判断对应起点是否为坏点。整点操作枚举该终点的所有入边,逐条修改。操作后 当且仅当答案为
YES。复杂度为 。在第二子任务的规模下,即使每次整点操作都枚举全部边也能通过。
4. 满分算法:随机指纹
为每个起点 独立生成三个 64 位随机权值 。以下运算均在无符号 64 位整数中自然溢出,即模 。
对每一维指纹维护
$$S_j=\sum_{(u,v)\text{ 当前可用}}h_j(u),\qquad T_j=\sum_{u=1}^n h_j(u).$$因为起点 的每条可用出边都贡献一次 ,所以
若所有 ,必有三维 。若出度向量错误,三个等式同时误碰撞的概率可以忽略不计;使用运行时随机种子还能避免输入针对固定权值构造。
为了支持整点操作,再为每个终点 维护当前可用入边的三维权值和 ,以及所有原始入边的权值和 :
- 摧毁 :从 中减去 ;
- 修复 :向 中加上 ;
- 摧毁终点为 的全部边:令 ,再令 ;
- 修复终点为 的全部边:令 ,再令 。
每次操作只做常数次无符号整数运算。总时间复杂度为 ,空间复杂度为 。
本解法是 Monte Carlo 算法。三组独立 64 位指纹将非零错误出度向量被误判的概率压到工程上可忽略的量级;正式数据还使用独立模数指纹 Oracle 与小规模精确算法交叉核验。
复杂度
- 子任务 1:时间 ,空间 ;
- 子任务 2:时间 ,空间 ;
- 满分算法:时间 ,空间 。
易错点
- 第 2、4 类操作修改的是终点为指定点的虫洞,而不是从该点出发的虫洞。
- 第 4 类操作必须恢复该终点的全部原始入边,包括此前被第 1 类操作单独摧毁的边。
- 只判断当前可用边数是否等于 不够;不同起点的出度可能分别为 和 。
- 单边操作的合法性由输入保证,整点操作则允许没有实际效果。
- 指纹和乘加必须使用无符号 64 位类型,避免有符号溢出未定义行为。
- 1
信息
- ID
- 1028
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 0
- 上传者