Trie + dp
Dictionary tree Training Questions in the big white book.
The question is how many small strings a string may contain.
For example
ABCD
4
A
B
CD
AB
ABCD = a + B + CD; ABCD = AB + CD;
Recursion: forward from the last digit, DP [I] = DP [I] + dp [I + Len [x] X is the input sequence and is appended to the node. Yes I ~ The prefix of strlen (s. S [1, 2, 3 ,..., I ,... Len]
When a trie tree is built, the sequence is also attached to the node.
Finally, search for the number of string prefixes and add them together.
#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<cmath>#define INF 0x7fffffff#define eps 1e-6#define LL long longusing namespace std;const int MOD=20071027;struct Trie{ int word[4001*100][26]; int ex[4001*100]; int size; void clear() { memset(word[0],0,sizeof(word[0])); size=1; ex[0]=0; } int insert(char *s,int v) { int u=0,c; for(int i=0; s[i]!='\0'; i++) { int c=s[i]-'a'; if(!word[u][c]) { memset(word[size],0,sizeof(word[size])); ex[size]=0; word[u][c]=size++; } u=word[u][c]; } ex[u]=v; } int search(char *s,int len,vector<int>& ans) { int u=0,c; for(int i=0; s[i]!='\0'&&i<len; i++) { c=s[i]-'a'; if(!word[u][c])return 0; u=word[u][c]; if(ex[u]) ans.push_back(ex[u]); } }} wo;char str[300001];int dp[300001];int n;int le[4001];int main(){ int nn=1; while(scanf("%s",str)!=EOF) { scanf("%d",&n); wo.clear(); memset(dp,0,sizeof(dp)); char tmp[101]; int len=strlen(str); for(int i=0; i<n; i++) { scanf("%s",tmp); le[i+1]=strlen(tmp); wo.insert(tmp,i+1); } dp[len]=1; for(int i=len-1; i>=0; i--) { vector<int>ans; wo.search(str+i,len-i,ans); for(int j=0; j<ans.size(); j++) dp[i]=(dp[i]+dp[i+le[ans[j]]])%MOD; } printf("Case %d: %d\n",nn++,dp[0]); }}