题意:
给定一个模式串P n个字串T
问p能有几种由T构成的方案。
eg:a,b,an,cd abcd ——> a+b+cd/ab+cd
分析:组成方案数
d(i)表示从i位置组成模式串P的方案数。
初始态:d(len)=1
d(i) =sum{ d(i, len(x))| x是s(i...l)的前缀 }
#include<bits/stdc++.h>
using namespace std;
#define N 500005
#define Mod 20071027
int d[N],n;
char str[N],s[N];
struct Trie{
int ch[N][26];
int val[N];
int sz; ///结点数量
void Init(){sz=1;memset(ch[0],0,sizeof(ch[0]));}
int idx(char c){return c-'a';}///字符c的编号
void Insert(char *s,int v){
int u=0,n=strlen(s);
for(int i=0;i<n;i++){
int c=idx(s[i]);
if(!ch[u][c])///结点不存在
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;///用val数组判断该结点是否是字串终止点
}
int Query(char *s,int pos){
int u=0,n=strlen(s),res=0;
for(int i=pos;i<n;i++){
int c=idx(s[i]);
if(ch[u][c]){
u=ch[u][c];
if(val[u]==1){
res=(res+d[i+1])%Mod;
}
}else {
break;
}
}
return res;
}
}v;
int main(){
int iCase=0;
while(~scanf("%s%d",str,&n)){
v.Init();
for(int i=0;i<n;i++){
scanf("%s",s);
v.Insert(s,1);
}
int len=strlen(str);
d[len]=1;
for(int i=len-1;i>=0;i--){
d[i]=v.Query(str,i);
}
printf("Case %d: %d\n",++iCase,d[0]);
}
}