ACC 4
CRT 竟然只要求模数互质,赛时受 exLucas 影响以为 CRT 要求模数都是质数(
痛失 AK,这下致敬 K8 了
A
懒得喷
B
扫描字符串,维护 \(c_i\) 表示到当前扫到的位置为止,有多少种字符串的最后一次出现左端点在 \(i\),
则询问 \([l,r]\) 的答案即为扫到 \(r\) 时 \([l,r]\) 的区间和。复杂度 \(O(n^2+q)\)。
C
对于能拼出的串 \(s\),考虑在其最长的,是给出的串的前缀的,前缀,处统计贡献,这样每种串只被统计一次,
建出前缀 Trie,对于每个节点 \(u\),若 \(u\) 没有 \(c\) 孩子,则 \(u\) 拼上任何一个以 \(c\) 开头的后缀形成的串都应该在 \(u\) 处统计贡献,
再建个反串前缀 Trie 对每个 \(c\) 统计出以 \(c\) 开头的后缀种类数,用上面的方法统计贡献即可。
注意 corner case。
D
模数小的话,只需要在线段树的每个节点上维护 \(f_i\) 表示 \(i\) 通过这个节点后会变成什么。
这题给的模数分解成 \(\prod p_i^{k_i}\) 之后 \(p_i^{k_i}\) 都很小,所以以每个 \(p_i^{k_i}\) 为模数求出答案后再 CRT 合并即可。
Bonus:B 题 \(O(n\log^2n+q\log n)\)(我知道没人问我):
考虑建出 SAM,则第 \(i\) 个 endpos 内的点最后一次出现位置肯定相同,假设它是 \(e_i\)。
仍然维护上述的 \(c_i\),考虑往后扫一个字符之后哪些点的 \(e_i\) 会发生变化,
发现扫到 \(r\) 时 SAM 上长度为 \(r\) 的前缀对应的节点根链上的点的 \(e_i\) 会变为 \(r\),
考虑每个点对 \(c\) 的贡献,发现 \(i\) 点对 \(c\) 的贡献为使 \([e_i-l_i+1,e_i-l_{f_i}]\) 区间加一,
(\(l_i\) 是 \(i\) 内最长串的长度,\(f_i\) 是 \(i\) 的 fail 指针)
可以发现,对于树链上 \(e_i\) 相同的一段(一个 \(e_i\) 颜色段),它们对 \(c\) 的贡献区间是连续的一段,
所以加入一个颜色段时,只需要对其上每个点的贡献区间连成的这一段区间加一,删除一个颜色段时只需要区间减一。
所以树剖套 ODT 维护 \(e_i\) 颜色段,每次覆盖某根链上 \(e_i\gets r\) 时,
删去这条链上原本的所有颜色段,再加入整条根链形成的 \(r\) 颜色段即可。