题意:
给出两个字符串s和t,其中t有两种意义,s中可能包含若干t,问s一共有多少种意义
思路:
KMP预处理出匹配位置,然后dp
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 111111;
const ll MOD = 1000000007;
int Next[MAXN];
bool vis[MAXN];
void getNext(char *t, int m) {
Next[0] = Next[1] = 0;
for (int i = 1; i < m; i++) {
int j = Next[i];
while (t[i] != t[j] && j > 0) j = Next[j];
Next[i + 1] = t[i] == t[j] ? j + 1 : 0;
}
}
void kmp(char *s, char *t, int n, int m) {
getNext(t, m);
memset(vis, false, sizeof(vis));
for (int i = 0, j = 0; i < n; i++) {
while (j && s[i] != t[j]) j = Next[j];
if (s[i] == t[j]) ++j;
if (j == m) vis[i] = true;
}
}
char s[MAXN], t[MAXN];
ll dp[MAXN];
int main() {
int T, cs = 0;
scanf("%d", &T);
while (T--) {
scanf("%s%s", s, t);
int n = strlen(s), m = strlen(t);
kmp(s, t, n, m);
dp[0] = 1;
for (int i = 1; i <= n; i++) {
dp[i] = dp[i - 1];
if (vis[i - 1]) {
dp[i] = (dp[i] + dp[i - m]) % MOD;
}
}
printf("Case #%d: %I64d\n", ++cs, dp[n]);
}
return 0;
}