前缀树保存字符串集合
#include<bits/stdc++.h> using namespace std; const int maxx=400005; const int mod=20071027; int idx(char c) {return c-'a';} int ch[maxx][30]; int val[maxx]; int sz; void insert(char* s) { int u=0,n=strlen(s); for(int i=0;i<n;++i) { int c=idx(s[i]); if(!ch[u][c]) { val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=1; } char s[300005],a[105]; int dp[300005]; int n,i; int main () { int cnt=0; while(scanf("%s",s)!=EOF) { reverse(s,s+strlen(s)); scanf("%d",&n); memset(ch,0,sizeof(ch)); memset(val,0,sizeof(val)); memset(dp,0,sizeof(dp)); sz=1; for(i=0;i<n;++i) { scanf("%s",a); insert(a); } int len=strlen(s); for(i=0;i<len;++i) { int u=0; for(int j=i;j>=0;--j) { int c=s[j]-'a'; if(ch[u][c]) u=ch[u][c]; else break; if(!val[u]) continue; else { if(j==0) dp[i]++,dp[i]%=mod; else dp[i]+=dp[j-1],dp[i]%=mod; } } } printf("Case %d: %d\n",++cnt,dp[strlen(s)-1]); } return 0; }