一些常见错误算法的卡法

· · 算法·理论

CF Hackers 看过来。毒瘤出题人看过来。

主要记录一些常用但是可以被卡的算法的卡法。由于作者太菜了,目前内容很少,欢迎大家私信补充。

字符串哈希

由于 cz 的帖子,现在哈希的卡法已经大众化了……

单哈希、ull 自然溢出、base 为常数但不给出

用 Thue Morse 序列。

证明过程直接照搬巨佬的题解,讲得很详细:

对于二进制串 s,定义 \bar s 为按位翻转后的串。令 0 阶 Thue Morse 序列 t_0=\texttt{0}t_n=t_{n-1}+\overline{t_{n-1}},有 \text{hash}(t_n)=b^{2^{n-1}}\text{hash}(t_{n-1})+\text{hash}(\overline{t_{n-1}})\text{hash}(\overline{t_n})=b^{2^{n-1}}\text{hash}(\overline{t_{n-1}})+\text{hash}(t_{n-1}),记 h_n=\text{hash}(t_n)-\text{hash}(\overline{t_n}),有 h_n=(b^{2^{n-1}}-1)h_{n-1}

由于 b^{2^{n-1}}-1=(b-1)(b^{2^{n-2}}+1)(b^{2^{n-3}}+1)\dots(b+1),而 b 是奇数,那么每一项都是偶数,故 2^n|b^{2^{n-1}}-1,那么 2^{\frac{n(n+1)}{2}}|f_n,对于 n\ge11\dfrac{n(n+1)}{2}>64,自然溢出就爆炸了。

那么输出长度为 2^{11} 的 Thue Morse 序列即可。

个人认为这个卡法很有趣,同时需要数学知识与构造能力。

单哈希、modint 范围内且给出、base 为常数且给出/不给出

给不给出 base 卡法都一样。

根据生日悖论,对于模数 p,期望 \sqrt{\dfrac{\pi p}{2}} 个字符串就能冲突,只要输出一个足够长的字符串即可。

双哈希、两个 mod 和两个 base 均给出

先随机求出符合前一组哈希的字符串,再以他们为字符集,求出满足第二组哈希的字符串即可。

unordered_set/map

本质上是卡哈希表。

orz 大神的博客。

经过查阅官方文档,C++ 官方哈希函数就是对值做一次哈希,再取一次模。所以只要疯狂往里面塞这些质数的倍数就能不停制造哈希冲突,从而把时间复杂度打到 \Theta(n^2)。经试验,126271/107897 是两个合适的质数。

SPFA

众所周知,关于 SPFA,___

以下摘自知乎:

朴素 SPFA

珂朵莉树复杂度的关键是推平操作,这样才能合并节点。那只要没有推平操作珂朵莉树就炸了……