Trie树上的DP 讲解白树有
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define SF scanf
#define PF printf
#define max(a, b) ((a) < (b) ? (b) : (a))
using namespace std;
typedef long long LL;
const int MAXN = 300000;
const int MAXL = 400000;
const int SZ = 26;
const int MOD = 20071027;
char s[MAXN+10];
int d[MAXN+10];
struct Trie_Tree
{
int ch[MAXL+10][SZ+10];
int val[MAXL+10];
int sz;
void init() {
sz = 1; val[0] = 0; memset(ch[0], 0, sizeof(ch[0]));
}
inline int ID(char c) { return c - 'a'; }
void insert(char *s)
{
int n = strlen(s), u = 0;
for(int i = 0; i < n; i++)
{
int c = ID(s[i]);
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = n;
}
void Find(char *s, int p, int Len)
{
int u = 0;
for(int i = 0; i < Len; i++)
{
int c = ID(s[i]);
if(!ch[u][c]) return ;
u = ch[u][c];
if(val[u]) d[p] = (d[p] + d[p + val[u]]) % MOD;
}
}
}trie;
int main()
{
int kase = 0;
char t[110];
while(~SF("%s", s))
{
int N; SF("%d", &N);
int Len = strlen(s);
trie.init();
d[Len] = 1;
for(int i = 0; i < N; i++) { SF("%s", t); trie.insert(t); }
for(int i = Len-1; i >= 0; i--)
{
d[i] = 0;
trie.Find(&s[i], i, Len-i);
}
PF("Case %d: %d\n", ++kase, d[0]);
}
return 0;
}