一个 n 个点的树,每条边的边权,给出 m 条路径。要求只改变一条边的边权,使得所有路径中长度最大的路径的长度最小。
n,m≤3×105。
分析
“最大值最小”提示我们要二分答案。假设我们当前要求最大路径长度不能超过 d。那么所有长度大于 d 的路径中都要包含操作的边,且操作的边的边权应当大于等于该路径的原长与 d 的差。
更进一步,这条边的边权应当大于等于所有路径长度最大值与 d 的差。所以,我们可以树上差分来给超过 d 的路径打标记,然后去遍历每一条边,查看是否存在一条边被所有的标记覆盖且边权大于等于路径长度最大值与 d 的差。
注意到通配符个数不超过 10,所以我们尝试从这里入手。首先我们可以把模式串用通配符分割成 h 段,其中每一段为确定的字符串或第一个字符为通配符剩下的字符为字符串。例如 a*b?c 会被分割为 a、*b 和 ?c 三部分。
定义状态 fk,i 表示待匹配串在第 i 个字符处能否匹配到第 k 段结尾。
接着考虑如何转移。我们用 str 表示模式串, s 表示待匹配串,posk 表示第 k 段结尾位置,lenk 表示第 k 段长度。
若第 k 段为确定的字符串,那么直接匹配再从前一段转移即可,即 fk,i=[fk−1,i−lenk∧strposk−lenk+1,posk=si−lenk+1,i]。
若第 k 段为开头为 ? 的字符串,那么直接匹配确定的部分,再跳过前一个字符转移即可,即 fk,i=[fk−1,i−lenk∧strposk−lenk+2,posk=si−lenk+2,i]。
若第 k 段为开头为 * 的字符串,那么直接匹配确定的部分,再跳过若干字符转移即可,即 fk,i=[∃(j≤i−lenk+1∧fk−1,j)∧strposk−lenk+2,posk=si−lenk+2,i]。
匹配用字符串哈希即可。
I Mex Game
题意
给定一个长度为 n+1(1≤n≤2×105) 的字符串 s。共 n 轮游戏,第 i 轮进行 i 次操作,每轮均由 Alice 先,与 Bob 交替往集合 X 中加入非负整数(一次加入即一次操作)。对于每一轮,记 x=mex(X),若 sx 为 A 则 Alice 胜,反之 Bob 胜。对于每一轮,输出谁胜。
分析
集合 A 中的数不可能成为 x,所以两人的策略都是不断加入下一个另一个人的字母出现的位置。又因为操作 i 次后,x 可能出现的范围为 [0,i]。所以我们只需要统计 [0,i] 中 A 和 B 出现的次数。如果对方字母出现的次数比自己能操作的次数多则输。