看到 OI Wiki 上有关 KMP 的一个不算惊为天人但也有点意思的做法,水一水。

众所周知 KMP 是为了解决字符串匹配问题的,有一个长度为 $n$ 的模式串 $t$ 和一个文本串 $s$。

我们构造一个字符串 $t+\#+s$​​​​,其中 $\#$​​​​ 是既不在 $t$​​​​ 中也不在 $s$​​​​ 中的一个字符。

求这个字符串的前缀数组(即 $nxt$ 函数),那么在该字符串中 $nxt[i]=n$​ 的位置就是一个匹配。

char a[maxn]; // 字符串从 1 开始
char b[maxn];
int n, m;
int nxt[maxn];

void solve()
{
    for (int i = 2, j = 0; i <= n + 1 + m; i++)
    {
        while (j && a[i] != a[j + 1])
            j = nxt[j];
        if (a[i] == a[j + 1])
            j++;
        nxt[i] = j;
    }
    for (int i = n + 2; i <= n + 1 + m; i++)
        if (nxt[i] == n)
            cout << i - 2 * n << endl;
}