int nxt[maxn]; char a[maxn], b[maxn];
void getNext(char p[]) {
int i = 0, k = -1, len = strlen(p);
nxt[i] = -1;
while(i < len) {
if(k == -1 || p[i] == p[k]) {
if(p[++i] != p[++k]) nxt[i] = k;
else nxt[i] = nxt[k]; // 注意
} else k = nxt[k];
}
}
// 匹配次数
int kmp_match(char t[], char p[]) {
int i = 0, j = 0, cnt = 0;
int n = strlen(t), m = strlen(p);
while(i <= n - 1) {
if(j < 0 || t[i] == p[j]) i++, j++;
else j = nxt[j];
if(j == m) cnt++, j = nxt[j];
}
return cnt;
}
// 匹配位置
int kmp_search(char t[], char p[]) {
int i = 0, j = 0;
int n = strlen(t), m = strlen(p);
while(i < n && j < m) {
if(j < 0 || t[i] == p[j]) i++, j++;
else j = nxt[j];
}
if(j == m) return i - j + 1;
else return -1;
}
int main() {
int n, m, T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
scanf("%s%s", a, b);
getNext(b);
int ans = kmp_search(a, b);
printf("%d\n", ans);
}
}
struct Trie{
static const int maxt = 1e7+5;
int rt, id, tot, t[maxt][2];
int cnt[maxt], val[maxt], end[maxt];
inline int newnode(){
++tot;
t[tot][0] = t[tot][1] = 0;
cnt[tot] = end[tot] = val[tot] = 0;
return tot;
}
inline void init(){
tot = 0;
rt = newnode();
}
inline void add(int x){
rt = 1;
for(int i=31; ~i; i--){
id = x >> i & 1;
if(!t[rt][id]) t[rt][id] = newnode();
rt = t[rt][id];
++cnt[rt];
}
end[rt] = 1, val[rt] = x;
}
inline int query(int x){
rt = 1;
for(int i=31; ~i; i--){
id = x >> i & 1;
if(t[rt][id^1]) rt = t[rt][id^1];
else rt = t[rt][id];
}
return x ^ val[rt];
}
} t;
给出若干字符串,问是否为原串的子序列
int n, t, nxt[maxn][30];
char s[maxn], str[maxn];
int main() {
scanf("%s", s+1);
int len = strlen(s+1);
for(int i=len; i; i--) {
for(int j=0; j<26; j++) nxt[i-1][j] = nxt[i][j];
nxt[i-1][s[i]-'a'] = i;
}
scanf("%d", &t);
while(t--){
scanf("%s", str);
int lenc = strlen(str), f = 0;
for(int i=0, now=0; i<lenc; i++){
now = nxt[now][str[i]-'a'];
if(!now) {
f = 1;
break;
}
}
if(f) puts("No");
else puts("Yes");
}
}
求子序列个数:
int n, nxt[maxn][30], f[maxn];
char s[105];
int dfs(int x) {
if(f[x]) return f[x];
for(int i=0; i<26; i++)
if(nxt[x][i]) f[x] += dfs(nxt[x][i]);
return ++f[x];
}
int main() {
scanf("%d%s", &n, s+1);
for(int i=n; i; i--) {
for(int j=0; j<26; j++) nxt[i-1][j] = nxt[i][j];
nxt[i-1][s[i]-'a'] = i;
}
int num = dfs(0);
printf("%d\n", num);
}