Remember the Word UVALive - 3942 DP_字典树

每个小单词的长度都是小于等于100的,这是个重要的突破口.

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 300006 
#define mod 20071027
using namespace std;
char str[maxn],wd[maxn]; 
int tag[maxn],n,f[maxn],m,cas; 
struct TRIE{
    #define SIGMA 30  
    int root,ch[maxn][SIGMA],cnt; 
    void init() {
        root = cnt = 0;
        memset(ch,0,sizeof(ch)); 
        memset(tag,0,sizeof(tag));
        memset(f,0,sizeof(f)); 
    }
    void ins(char s[]) {
        int len = strlen(s),p = root; 
        for(int i = 0;i < len; ++i) {
            if(!ch[p][s[i]-'a']) ch[p][s[i]-'a'] = ++cnt;
            p = ch[p][s[i]-'a'];
        }
        tag[p] = 1; 
    }
    void solve(int st){
        int p = root;
        for(int i = st;i <= m; ++i) {
            p = ch[p][str[i]-'a'];
            if(!p) break;
            if(tag[p]) f[st] += f[i + 1],f[st] %= mod; 
            if(tag[p] && i == m) f[st] += 1; 
        } 
    }
}trie; 
int main(){
    //setIO("input");
    while(scanf("%s",str) != EOF) {
        scanf("%d",&n),trie.init(),m = strlen(str) - 1; 
        for(int i = 1;i <= n; ++i) scanf("%s",wd),trie.ins(wd);
        for(int i = m;i >= 0; --i) trie.solve(i); 
        printf("Case %d: %d\n",++cas,f[0]); 
    }
    return 0; 
}

  

posted @ 2019-02-11 01:28  EM-LGH  阅读(164)  评论(0编辑  收藏  举报