
这题说的是给了一个长的字符串长度最大300000,又给了4000个单词 单词的长度不超过100.计算这个字符串能组成多少种不同单词的组合,求出方案总数。dp[i]以第i个字符为开始的字符串能有多少种的组成方案,这样每次去比较肯定是会超时的,然后可以用Trie树去优化,这样最多枚举100位种比4000位来得快很多
#include <iostream>
#include <cstdio>
#include <string.h>
#include <vector>
using namespace std;
const int maxn = *+;
const int signma_size =;
const int mod = ;
struct Trie{
int ch[maxn][signma_size];
int val[maxn];
int sz;
Trie(){ sz=; memset(ch[],,sizeof(ch[]));}
int idx(char c){ return c-'a'; }
void clear(){ sz=; memset(ch[],,sizeof(ch[])); }
void insert(char *s,int v){
int u=,n=strlen(s);
for(int i=; i<n; ++i){
int c= idx(s[i]);
if(ch[u][c]==){
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
void find(char *s,int n,vector<int> &va)
{
int u=;
for(int i=; i<n; ++i){
int c=idx(s[i]);
if(ch[u][c]==) break;
u=ch[u][c];
if(val[u]!=) va.push_back(val[u]);
}
}
}A;
char text[],str[][];
int Len[],dp[];
int main()
{
int S,cas=;
while(scanf("%s%d",text,&S)==){
A.clear();
int n=strlen(text);
for(int i=; i<=S; i++){
scanf("%s",str[i]);
A.insert(str[i],i);
Len[i]=strlen(str[i]);
}
dp[n]=;
vector<int> Val;
for(int i=n-; i>=; i--){ A.find(text+i,n-i,Val);
dp[i]=;
int L=Val.size();
for(int j=; j<L; ++j){
int t=Val[j];
dp[i]=( dp[i] + dp[ i+Len[ t ] ])%mod;
}
Val.clear();
}
printf("Case %d: %d\n",++cas,dp[]);
}
return ;
}