CF1556F Sports Betting
可以对每个人分开考虑,最终答案就是总和。状压dp,(f_i) 表示 (x) 赢了 (i) 里的所有人的概率。转移的时候可以枚举一个集合 (j),表示新赢了这些人。但如果直接转移会出现重复,考虑容斥,计算不满足的概率。这时候只要让 (j,i) 集合之间打架的时候全让 (j) 里的人赢就可以了。因为这样划分后,每次转移里 (x) 能打败的集合是唯一确定的,所以不会重复。
然后又发现,每个人的转移都有大量的重叠部分,那么继续优化。把每次对战看成一条图上的边。设 (f_i) 表示集合 (i) 构成一整个SCC的概率,还是要用容斥转移。如果不构成强连通,则有多个SCC,并且由于原图是竞赛图(完全有向图),缩点后SCC构成一条链,那么只需要枚举第一个SCC的状态,就可以做到不重不漏的。这样省去了最外重的循环,可以在 (3^n) 时间内求解。最后 (f_i) 对答案的贡献容易推导
注意,如果转移的时候不用递推而是暴力,就会多出一个 (n)。
CF1556G Gates to Another World
暴力地进行连边,复杂度为 (O(2^nn))。根据题意不难发现这 (2^n) 个点可以分为 (m) 段,应该是想让我们一段一段处理,那么直接上线段树。原题“只有一个二进制位不同”相当于将线段树上某个节点的左右子树重叠位置连边。
因为共有 (2^n) 个点,所以线段树上每个节点对应的区间长度也是 (2^k),这个性质可以保证每个节点对应区间内的点构成联通图(如果这些点都没被删),所以每个节点内不用考虑。
每条线段对应 (n) 个节点,那么树上有用的节点为 (nm)。考虑在这些节点之间使用并查集连边。根据上面所说的“左右子树重叠”操作,不难发现每个点最多跟 (n) 个点连边,所以边数为 (n^2m)。
具体操作的时候,先把询问倒叙,删除变成插入。然后可以先把整棵树建出来,存下每个时刻要加的边。应该也可以一边处理询问一边动态在线段树上修改连边(像普通线段树打标记那样)。复杂度 (n^2m alpha),后面那个是并查集