题意:给出n个单词和一段文章,问用这n个单词,有多少种方法翻译这篇文章
/*
字典树+dp
枚举1~len,dp[i]表示到第i个字符有多少种方法,当然第0个字符自然有且只有一个方法,dp[0]=1
如果能从j+1翻译到i dp[i]+=dp[j] (0<=j<i)
*/
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 5e5 + 5;
const int mod = 835672545;
struct node{
int nxt[26];
int ed;
void Init(){
memset(nxt,-1,sizeof(nxt));
ed=0;
}
}L[maxn];
char st[maxn];
int tot;
int dp[maxn];
void add(char a[],int len){
int tmp,now=0;
for(int i=0;i<len;i++){
tmp=a[i]-'a';
if(L[now].nxt[tmp]==-1){
L[++tot].Init();
L[now].nxt[tmp]=tot;
}
now=L[now].nxt[tmp];
}
L[now].ed=1; //标记到达末尾
}
int query(int s,int ed){
int tmp,now=0;
for(int i=s;i<=ed;i++){
tmp=st[i]-'a';
if(L[now].nxt[tmp]==-1) return 0;
now=L[now].nxt[tmp];
}
return L[now].ed; //如果该节点是单词末尾,表示能从s翻译到ed
}
int main(){
int T,n;
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
tot=0;
memset(dp,0,sizeof(dp));
L[0].Init();
scanf("%d",&n);
while(n--){
scanf("%s",st);
add(st,strlen(st));
}
scanf("%s",st);
int len=strlen(st);
for(int i=len;i>0;i--) st[i]=st[i-1]; //本来脑残从1到len循环结果WA了
dp[0]=1;
for(int i=1;i<=len;i++){
for(int j=0;j<i;j++){
if(query(j+1,i)) {
dp[i]=(dp[i]+dp[j])%mod;
}
}
}
printf("%d\n",dp[len]);
}
return 0;
}