题意
模式串第 (i) 个位置可以有 (a_i) 个字符满足要求,给出这 (a_i) 个字符。给出一个主串,输出主串中所有能与模式串匹配的子串。
思路
Shift-And 算法:学习传送门
Shift-And 算法基本上也只适用这种给出模式串字母表的情况,因模式串有太多种可能而不能用 kmp 算法,这道题就是根据 Shift-And 的解法特性来出的。时间复杂度 (O(nm/x)) ,(n) 为主串长度,(m) 为模式串长度,(x) 为计算机的位数。
代码实现
#include <cstdio>
#include <bitset>
using std::bitset;
bitset<1010> b[11], D; // b[i][j]=1表示i这个值可以放在模式串的第j个位置
char s[5000010];
int main() {
int n;
while (~scanf("%d", &n)) {
for (int i = 0; i < 11; i++) b[i].reset();
D.reset();
for (int i = 0, nn, x; i < n; i++) {
scanf("%d", &nn);
while (nn--) {
scanf("%d", &x);
b[x].set(i);
}
}
getchar();
fgets(s, 5000005, stdin);
for (int i = 0; s[i]; i++) {
D <<= 1;
D.set(0);
D &= b[s[i]-'0'];
if (D[n-1]) {
char tmp = s[i+1];
s[i+1] = ' ';
puts(s + i-n+1);
s[i+1] = tmp;
}
}
}
return 0;
}