题意:给出一个长字符串 s ,再给出 n 个短字符串,问用短字符串构成长字符串 s 有多少种方案;
#include <stdio.h>
#include <string.h>
using namespace std;
const int N = 3e5 + 10, Mod = 20071027;
int n, p = 0;
int dp[N];
char s[N], f[101];
struct xx{
int cnt;
xx *nex[26];
xx(){
cnt = 0;
memset(nex, NULL, sizeof nex);
}
};
void Insert(xx *root, char a[]){
int l = strlen(a);
xx *p = root;
for(int i = 0; i < l; i++){
int id = a[i]-'a';
if(p->nex[id] == NULL){
p->nex[id] = new xx();
}
p = p->nex[id];
}
(p->cnt)++;
}
void Query(xx *root, char a[]){
int l = strlen(a);
dp[l] = 1;
for(int i = l-1; i >= 0; i--){
xx *p = root;
for(int j = i, k = 1; j < l; j++, k++){
int id = a[j]-'a';
if(p->nex[id] != NULL){
p = p->nex[id];
if(p->cnt) dp[i] = (dp[i]+dp[i+k])%Mod;
}
else break;
}
}
}
void Delete(xx *root){
xx *p = root;
for(int i = 0; i < 26; i++){
if(p->nex[i] != NULL){
Delete(p->nex[i]);
}
}
delete p;
}
int main(){
while(scanf("%s", s) == 1){
xx *root = new xx();
memset(dp, 0, sizeof dp);
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%s", f);
Insert(root, f);
}
Query(root, s);
printf("Case %d: %d\n", ++p, dp[0]);
Delete(root);
}
}