【题解】CF472G Design Tutorial: Increase the Constraints
《正解分块 + FFT 跑 1min,__builtin_popcount 暴力跑 10s》
《没人写正解,CF 也不卡》
思路
正解:分块 + FFT
乱搞:__builtin_popcount
首先我们知道哈明距离可以用一种 \(O(|字符集| |S|)\) 的算法求。
具体考虑枚举字符集中的每一个字符,将两个串中是该字符的位置看作 \(1\),不是该字符的位置看作 \(0\),然后数不同的位置就行。
基于这个思路,考虑把 \(0, 1\) 转成二进制直接异或再 __builtin_popcount 就可以得到一种暴力,卡一下常就过了。
但是我们需要一个看起来是正解,复杂度也是正解的做法,不然会遭天谴!
于是考虑到哈明距离的另一种求法:同样转化成 \(0, 1\),但是求出所有对应位置的乘积之和再容斥算哈明距离。
假设 \(p_2 - p_1 = k\) 位,不考虑 \(len\) 的情况下答案是 \(\sum\limits_{i = p1}^{n - k} A_i B_{i + k}\).
发现是一个差卷积的形式,无视剩下的限制就可以直接 NTT \(O(n \log n)\) 算。
剩下的限制不太好做,考虑到每次都算差卷积很浪费时间,想一想块块做法。
考虑把 \(B\) 分块,然后每一块都和 \(A\) 预处理差卷积。
然后散块暴力算哈明距离,整块直接调用就行。
复杂度大概要算一下最优块长,不然感觉过不了。
代码不是我自己写的就不放了。