n
x
t
[
i
]
[
j
]
nxt[i][j]
nxt[i][j] 表示在原串
s
s
s 第
i
i
i 位后面的第一个
j
j
j 出现的位置
设串长为
n
n
n ,字符集大小为
a
a
a ,则时间复杂度为
O
(
n
∗
a
)
O(n*a)
O(n∗a)
其他应用:点我啊点我啊 O(∩_∩)O
给出若干字符串,问是否为原串的子序列
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 1e9 + 7;
const int maxn = 1e6 + 10;
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");
}
}
求子序列个数:
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 1e9 + 7;
const int maxn = 3e3 + 10;
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);
}