topic:
Meaning of the questions:
After each segment of the substring given M, ask how many letter string division manner, such that M is a sub-division string
analysis:
The question how many each prefix requires division manner, readily occur recursive definition DP [i] denotes the i-th prefix end how many division manner, the transfer is not difficult, it is assumed that the suffix letter string matching prefix a substring of length len, the dp [i] + = dp [i-len], to quickly find all matching substring just hit AC automatic machine, to use this last optimization, i.e. a pointer to fail node can match the success of the jump
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+25;
const LL mod = 1e9+7;
char s[MAXN],ss[MAXN];
int tire[MAXN][26],num[MAXN],fail[MAXN],last[MAXN],dp[MAXN],cnt,t,n,m;
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void init(int x)
{
for(int i = 0;i < 26; ++i) tire[x][i] = 0;
num[x] = 0;
last[x] = 0;
}
void Build_ac(char *s)
{
int root = 0,len = strlen(s),t;
for(int i = 0;i < len; ++i){
t = s[i] - 'a';
if(!tire[root][t]){
tire[root][t] = ++cnt;
init(cnt);
}
root = tire[root][t];
}
num[root] = len;
}
void Get_fail()
{
queue<int> p;
for(int i = 0; i < 26; ++i){
int son = tire[0][i];
if(son){
fail[son] = 0;
p.push(son);
}
else tire[0][i] = 0;
}
while(!p.empty())
{
int x = p.front();p.pop();
for(int i = 0; i < 26; ++i){
if(tire[x][i]){
int son = tire[x][i];
fail[son] = tire[fail[x]][i];
p.push(son);
if(num[fail[son]]) last[son] = fail[son];
else last[son] = last[fail[son]];
}
else tire[x][i] = tire[fail[x]][i];
}
}
}
void Query_ac(char *s)
{
int root = 0,len = strlen(s);
for(int i = 0;i < len; ++i){
LL ans = 0;
root = tire[root][s[i]-'a'];
for(int j = root; j ; j = last[j]){
if(!num[j]) continue;
ans += dp[i+1-num[j]];
if(ans >= mod) ans -= mod;
}
dp[i+1] = ans%mod;
}
}
int main()
{
scanf("%d",&t);
dp[0] = 1;
while(t--)
{
init(0);cnt = 0;
scanf("%d %d",&n,&m);
scanf("%s",ss);
while(m--){
scanf("%s",s);
Build_ac(s);
}
Get_fail(); Query_ac(ss);
for(int i = 1;i < n; ++i) write(dp[i]),putchar(' ');
printf("%d\n",dp[n]);
}
return 0;
}