【Description】
Hamed has recently found a string t and suddenly became quite fond of it. He spent
several days trying to find all occurrences of t in other strings he had. Finally
he became tired and started thinking about the following problem. Given a string s
how many ways are there to extract k ≥ 1 non-overlapping substrings from it such
that each of them contains string t as a substring? More formally, you need to
calculate the number of ways to choose two sequences a1, a2, ..., ak and b1, b2, ...,
bk satisfying the following requirements:
>k≥1>∀i(1≤i≤k)1≤ai,bi≤|s|>∀i(1≤i≤k)bi≥ai>∀i(2≤i≤k)ai≥bi−1>∀i(1≤i≤k)tisasubstringofstringsaisai + 1...sbi(stringsisconsideredas1−indexed).>
As the number of ways can be rather large print it modulo 10^9 + 7.
Input consists of two lines containing strings s and t (1 ≤ |s|, |t| ≤ 105). Each string
consists of lowercase Latin letters.
【Output】
Print the answer in a single line.
【Examples】
ababa
aba
Sample Output
5
welcometoroundtwohundredandeightytwo
d
Sample Output
274201
ddd
d
Sample Output
12
【Problem Description】
问字符串s中有多少个字串其中存在字串t
【Solution】
dp,KMP字符串匹配
定义dp[i]为前i个位置满足条件的答案数。val[i]为最后一个完全匹配时的初始位置,比如
s="abcde",t="bcd",则val[1]=val[2]=val[3]=0,val[4]=val[5]=2,sum[i]为dp数组的前缀和,
则状态转移方程为:
dp[i]=dp[i-1]+(dp[0]+1)+(dp[1]+1)+(dp[2]+1)+(dp[3]+1)+...+(dp[val[i]-1]+1),
其中dp[0]=0,整理一下得dp[i]=dp[i-1]+dp[1]+dp[2]+dp[3]+...+dp[i-t.size()]+i-t.size()+1
=dp[i-1]+sum[val[i]-1]+val[i];
val数组可以用kmp预处理出来。
【Code】
#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 100005
#define mod 1000000009
int Next[maxn];
int val[maxn];
int dp[maxn];
int sum[maxn];
char s[maxn],t[maxn];
void getval()
{
int j=1,k=0;
int tsize=strlen(t+1),ssize=strlen(s+1);
while(j<tsize)
{
if(k==0||t[j]==t[k])
{
k++;
j++;
Next[j]=k;
}
else k=Next[k];
}
int i=1;j=1;
while(i<ssize)
{
if(j==tsize&&s[i]==t[j])
{
val[i]=i-tsize+1;
j=Next[j];
}
if(j==0||s[i]==t[j])
{
i++;
j++;
}
else j=Next[j];
}
if (j == tsize && s[i] == t[j])
{
val[i] = i - tsize + 1;
j = Next[j];
}
}
Int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s+1>>t+1;
getval();
for(int i=1;i<=strlen(s+1);i++) if(!val[i]) val[i]=val[i-1];
for(int i=1;i<=strlen(s+1);i++)
{
dp[i]=dp[i-1]%mod;
if(val[i]) dp[i]=(dp[i]+sum[val[i]-1]+val[i])%mod;
sum[i]=(sum[i-1]+dp[i])%mod;
}
cout<<dp[strlen(s+1)]%mod<<endl;
cin.get(),cin.get();
return 0;
}