对于每种字符 (c in Sigma),构造掩码 (B_c),其中 (B_c[i]=[s[i]=c])。维护二进制串 (D),假设当前文本串扫描到了第 (i) 位,则 (D[j]=1) 当且仅当模式串的前缀 (p[1..j]) 与文本串前缀 (s[1..i]) 的长度为 (j) 的后缀完全相等。
每次读入一个新字符后,将 (D) 左移一位并加上 (1),与该位字符对应的掩码按位与,得到新的 (D)。
如果存在某次操作后,使得 (D) 的最高位是 (1),根据定义,即此时文本串当前前缀的长度为 (|p|) 的后缀与 (p) 完全相同,则 (i) 是一个匹配成功的末尾位置。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 10005;
bitset<N> b[N],d;
char s[N],p[N];
int ls,lp;
signed main()
{
ios::sync_with_stdio(false);
cin>>s+1>>p+1;
ls=strlen(s+1);
lp=strlen(p+1);
for(int i=1;i<=lp;i++)
{
b[p[i]][i]=1;
}
for(int i=1;i<=ls;i++)
{
d<<=1;
d[1]=1;
d&=b[s[i]];
if(d[lp]) cout<<i<<" ";
}
}