题目链接
有2个串,A,B,B有2个意思,问A串可以有几种表达的形式
dp[i]:表示以i结尾的种类数,如果A串从i-strlen(B)到i位置与B匹配,那么dp[i+1]=dp[i]+dp[i-strlen(B)],否则dp[i+1]=dp[i],用kmp记录匹配的结束位置。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
#include<vector>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define LL long long
#define pb push_back
#define gcd __gcd
#define For(i,j,k) for(int i=(j);i<k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)
const int maxn = 2e5+200;
const LL inf = 1LL << 34;
const LL mod = 1000000007;
int Next[maxn];
char a[maxn],b[maxn];
void getnext(char*s) {
int i=0,j=-1;
Next[0]=-1;
int len=strlen(s);
while(i<len) {
if(j==-1||s[i]==s[j])
Next[++i]=++j;
else
j=Next[j];
}
}
int x[maxn];
void kmp(char*p,char*s) {
int i=0,j=0;
int n=strlen(p);
int m=strlen(s);
while(i<n&&j<m) {
if(j==-1||p[i]==s[j])
i++,j++;
else
j=Next[j];
if(j==m) {
x[i-1]=1;
j=Next[j];
}
}
}
LL dp[maxn];
int main() {
int T;scanf("%d",&T);
int cas = 1;
while(T--) {
cl(dp,0);cl(x,0);
scanf("%s%s",b,a);
int len = strlen(a);
int N = strlen(b);
getnext(a);
kmp(b,a);
dp[0]=1;
for(int i=0;i<N;i++){
if(!x[i])dp[i+1]=dp[i];
else dp[i+1]=(dp[i]+dp[i+1-len])%mod;
}
printf("Case #%d: %lld\n",cas++,dp[N]%mod);
}
return 0;
}