天天看點

cf494b kmp&&dp

http://www.elijahqi.win/archives/487

B. Obsessive String

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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

t is a substring of string saisai + 1… sbi (string s is considered as 1-indexed).

As the number of ways can be rather large print it modulo 109 + 7.

Input

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

Input

ababa

aba

Output

5

Input

welcometoroundtwohundredandeightytwo

d

Output

274201

Input

ddd

d

Output

12

這題今晚寫的有點神志不清了,明天還得搭乘航班飛往胡志明,先留坑,明早填坑的。

滿足以下條件

1、集合中的所有串都是s的子串,且互不重疊 2、集合中的所有串都含有子串t。

設串s長度為n,串t長度為m,我們首先用kmp在s中比對t,比對成功的位置我們打下标記flag[i]=1(s[i-m+1…i]=t[1..m]).

設f[i]表示在s中以i結尾的集合數目,sum1[i]為fp[1..i]得字首和,sum2[i]為sum1[1..i]得字首和。如果flag[i]為0,則f[i]=f[i-1]。如果flag[i]為1,則dp[i]=i-m+1+sum2[i-m]。證明:若flag[i]=1,說明s[i-m+1…i]=t[1..m],那麼sj..i都含有子串t,如果集合中隻有一個串的話,一共有i-m+1種,如果在集合中有兩個以上比對的,那麼假設我們選擇其中一個串,能和他比對的串,因為不能重疊,是以是f[1]+f[2]+..+f[j-1]即sum1[j-1],那麼所有的可能就是sum1[1]+sum1[2]…+sum1[i-m],即sum2[i-m]。是以f[i]=i-m+1+sum2[i-m]

解釋一下這個推導過程,大概就是多個完全比對的時候,那麼目前這個,同若隻有一個的時候i-m+1

然後前面每個完全比對的就由sum2提供,在紙上畫一下 假設一個s串,然後t在其中有三個比對的,然後就可以明白了

http://blog.csdn.net/icefox_zhx/article/details/76038942

#include<cstdio>
#include<cstring>
#define mod 1000000007
#define N 100100
bool flag[N];
int f[N],sum1[N],sum2[N],next[N];
char s[N],t[N];
long long ans;
int main(){
    freopen("cf494b.in","r",stdin);
//  freopen("cf494b.out","w",stdout);
    scanf("%s%s",s+,t);
    int i=,j=-,n=strlen(t);next[]=-;
    while (i<n){
        if (j==-||t[i]==t[j]){
            ++i;++j;next[i]=j;
        }else j=next[j];
    }
    for (int i=n;i>=;--i) t[i]=t[i-];
    int m=strlen(s+);int k=;
    for (int i=;i<=m;++i){
        while (k&&s[i]!=t[k+]) k=next[k];
        if (t[k+]==s[i])++k;
        if (k==n) flag[i]=true;
    }
    for (int i=;i<=m;++i){
        if (flag[i]){
            (f[i]=i-n++sum2[i-n])%=mod;
        }else f[i]=f[i-];
        sum1[i]=(sum1[i-]+f[i])%mod;
        sum2[i]=(sum2[i-]+sum1[i])%mod;
    }
    for (int i=;i<=m;++i) (ans+=f[i])%=mod;
    printf("%d",ans);
    return ;
}